dependencies = [
"advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bufstream 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargotest 0.1.0",
"crates-io 0.2.0",
"crossbeam 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"curl 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "cargotest"
+version = "0.1.0"
+dependencies = [
+ "bufstream 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo 0.11.0",
+ "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "git2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hamcrest 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tar 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "cmake"
version = "0.1.16"
hamcrest = "0.1"
bufstream = "0.1"
filetime = "0.1"
+cargotest = { path = "tests/cargotest" }
[[bin]]
name = "cargo"
test = false
doc = false
-
-[[test]]
-name = "tests"
-
-[[test]]
-name = "resolve"
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use cargotest::support::{project, execs};
+use cargotest::support::registry::Package;
+use hamcrest::assert_that;
+
+#[test]
+fn bad1() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", r#"
+ [target]
+ nonexistent-target = "foo"
+ "#);
+ assert_that(foo.cargo_process("build").arg("-v")
+ .arg("--target=nonexistent-target"),
+ execs().with_status(101).with_stderr("\
+[ERROR] expected table for configuration key `target.nonexistent-target`, \
+but found string in [..]config
+"));
+}
+
+#[test]
+fn bad2() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", r#"
+ [http]
+ proxy = 3.0
+ "#);
+ assert_that(foo.cargo_process("publish").arg("-v"),
+ execs().with_status(101).with_stderr("\
+[ERROR] Couldn't load Cargo configuration
+
+Caused by:
+ failed to load TOML configuration from `[..]config`
+
+Caused by:
+ failed to parse key `http`
+
+Caused by:
+ failed to parse key `proxy`
+
+Caused by:
+ found TOML configuration value of unknown type `float`
+"));
+}
+
+#[test]
+fn bad3() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", r#"
+ [http]
+ proxy = true
+ "#);
+ assert_that(foo.cargo_process("publish").arg("-v"),
+ execs().with_status(101).with_stderr("\
+[UPDATING] registry `https://[..]`
+[ERROR] invalid configuration for key `http.proxy`
+expected a string, but found a boolean in [..]config
+"));
+}
+
+#[test]
+fn bad4() {
+ let foo = project("foo")
+ .file(".cargo/config", r#"
+ [cargo-new]
+ name = false
+ "#);
+ assert_that(foo.cargo_process("new").arg("-v").arg("foo"),
+ execs().with_status(101).with_stderr("\
+[ERROR] Failed to create project `foo` at `[..]`
+
+Caused by:
+ invalid configuration for key `cargo-new.name`
+expected a string, but found a boolean in [..]config
+"));
+}
+
+#[test]
+fn bad5() {
+ let foo = project("foo")
+ .file(".cargo/config", r#"
+ foo = ""
+ "#)
+ .file("foo/.cargo/config", r#"
+ foo = 2
+ "#);
+ foo.build();
+ assert_that(foo.cargo("new")
+ .arg("-v").arg("foo").cwd(&foo.root().join("foo")),
+ execs().with_status(101).with_stderr("\
+[ERROR] Couldn't load Cargo configuration
+
+Caused by:
+ failed to merge key `foo` between files:
+ file 1: [..]foo[..]foo[..]config
+ file 2: [..]foo[..]config
+
+Caused by:
+ expected integer, but found string
+"));
+}
+
+#[test]
+fn bad_cargo_config_jobs() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", r#"
+ [build]
+ jobs = -1
+ "#);
+ assert_that(foo.cargo_process("build").arg("-v"),
+ execs().with_status(101).with_stderr("\
+[ERROR] build.jobs must be positive, but found -1 in [..]
+"));
+}
+
+#[test]
+fn default_cargo_config_jobs() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", r#"
+ [build]
+ jobs = 1
+ "#);
+ assert_that(foo.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn good_cargo_config_jobs() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", r#"
+ [build]
+ jobs = 4
+ "#);
+ assert_that(foo.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn invalid_global_config() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+
+ [dependencies]
+ foo = "0.1.0"
+ "#)
+ .file(".cargo/config", "4")
+ .file("src/lib.rs", "");
+
+ assert_that(foo.cargo_process("build").arg("-v"),
+ execs().with_status(101).with_stderr("\
+[ERROR] Couldn't load Cargo configuration
+
+Caused by:
+ could not parse TOML configuration in `[..]config`
+
+Caused by:
+ could not parse input as TOML
+[..]config:1:2 expected `=`, but found eof
+
+"));
+}
+
+#[test]
+fn bad_cargo_lock() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("Cargo.lock", "")
+ .file("src/lib.rs", "");
+
+ assert_that(foo.cargo_process("build").arg("-v"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse lock file at: [..]Cargo.lock
+
+Caused by:
+ expected a section for the key `root`
+"));
+}
+
+#[test]
+fn bad_git_dependency() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+
+ [dependencies]
+ foo = { git = "file:.." }
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(foo.cargo_process("build").arg("-v"),
+ execs().with_status(101).with_stderr("\
+[UPDATING] git repository `file:///`
+[ERROR] Unable to update file:///
+
+Caused by:
+ failed to clone into: [..]
+
+Caused by:
+ [[..]] 'file:///' is not a valid local file URI
+"));
+}
+
+#[test]
+fn bad_crate_type() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+
+ [lib]
+ crate-type = ["bad_type", "rlib"]
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(foo.cargo_process("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+warning: crate-type \"bad_type\" was not one of lib|rlib|dylib|staticlib
+[COMPILING] foo v0.0.0 (file:///[..])
+[RUNNING] `rustc [..] --crate-type rlib [..]`
+"));
+}
+
+#[test]
+fn malformed_override() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+
+ [target.x86_64-apple-darwin.freetype]
+ native = {
+ foo: "bar"
+ }
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(foo.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ could not parse input as TOML
+Cargo.toml:[..]
+
+"));
+}
+
+#[test]
+fn duplicate_binary_names() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "qqq"
+ version = "0.1.0"
+ authors = ["A <a@a.a>"]
+
+ [[bin]]
+ name = "e"
+ path = "a.rs"
+
+ [[bin]]
+ name = "e"
+ path = "b.rs"
+ "#)
+ .file("a.rs", r#"fn main() -> () {}"#)
+ .file("b.rs", r#"fn main() -> () {}"#);
+
+ assert_that(foo.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ found duplicate binary name e, but all binary targets must have a unique name
+"));
+}
+
+#[test]
+fn duplicate_example_names() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "qqq"
+ version = "0.1.0"
+ authors = ["A <a@a.a>"]
+
+ [[example]]
+ name = "ex"
+ path = "examples/ex.rs"
+
+ [[example]]
+ name = "ex"
+ path = "examples/ex2.rs"
+ "#)
+ .file("examples/ex.rs", r#"fn main () -> () {}"#)
+ .file("examples/ex2.rs", r#"fn main () -> () {}"#);
+
+ assert_that(foo.cargo_process("build").arg("--example").arg("ex"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ found duplicate example name ex, but all binary targets must have a unique name
+"));
+}
+
+#[test]
+fn duplicate_bench_names() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "qqq"
+ version = "0.1.0"
+ authors = ["A <a@a.a>"]
+
+ [[bench]]
+ name = "ex"
+ path = "benches/ex.rs"
+
+ [[bench]]
+ name = "ex"
+ path = "benches/ex2.rs"
+ "#)
+ .file("benches/ex.rs", r#"fn main () {}"#)
+ .file("benches/ex2.rs", r#"fn main () {}"#);
+
+ assert_that(foo.cargo_process("bench"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ found duplicate bench name ex, but all binary targets must have a unique name
+"));
+}
+
+#[test]
+fn duplicate_deps() {
+ let foo = project("foo")
+ .file("shim-bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("shim-bar/src/lib.rs", r#"
+ pub fn a() {}
+ "#)
+ .file("linux-bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("linux-bar/src/lib.rs", r#"
+ pub fn a() {}
+ "#)
+ .file("Cargo.toml", r#"
+ [package]
+ name = "qqq"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = { path = "shim-bar" }
+
+ [target.x86_64-unknown-linux-gnu.dependencies]
+ bar = { path = "linux-bar" }
+ "#)
+ .file("src/main.rs", r#"fn main () {}"#);
+
+ assert_that(foo.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ found duplicate dependency name bar, but all dependencies must have a unique name
+"));
+}
+
+#[test]
+fn unused_keys() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+
+ [target.foo]
+ bar = "3"
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(foo.cargo_process("build"),
+ execs().with_status(0).with_stderr("\
+warning: unused manifest key: target.foo.bar
+[COMPILING] foo v0.1.0 (file:///[..])
+"));
+}
+
+#[test]
+fn empty_dependencies() {
+ let p = project("empty_deps")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "empty_deps"
+ version = "0.0.0"
+ authors = []
+
+ [dependencies]
+ foo = {}
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ Package::new("foo", "0.0.1").publish();
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr_contains("\
+warning: dependency (foo) specified without providing a local path, Git repository, or version \
+to use. This will be considered an error in future versions
+"));
+}
--- /dev/null
+extern crate hamcrest;
+extern crate cargotest;
+
+use cargotest::support::{project, execs, main_file, basic_bin_manifest};
+use hamcrest::{assert_that};
+
+fn assert_not_a_cargo_toml(command: &str, manifest_path_argument: &str) {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process(command)
+ .arg("--manifest-path").arg(manifest_path_argument)
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(101)
+ .with_stderr("[ERROR] the manifest-path must be a path \
+ to a Cargo.toml file"));
+}
+
+
+fn assert_cargo_toml_doesnt_exist(command: &str, manifest_path_argument: &str) {
+ let p = project("foo");
+ let expected_path = manifest_path_argument
+ .split("/").collect::<Vec<_>>().join("[..]");
+
+ assert_that(p.cargo_process(command)
+ .arg("--manifest-path").arg(manifest_path_argument)
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(101)
+ .with_stderr(
+ format!("[ERROR] manifest path `{}` does not exist",
+ expected_path)
+ ));
+}
+
+#[test]
+fn bench_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("bench", "foo");
+}
+
+#[test]
+fn bench_dir_plus_file() {
+ assert_not_a_cargo_toml("bench", "foo/bar");
+}
+
+#[test]
+fn bench_dir_plus_path() {
+ assert_not_a_cargo_toml("bench", "foo/bar/baz");
+}
+
+#[test]
+fn bench_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("bench", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn build_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("build", "foo");
+}
+
+#[test]
+fn build_dir_plus_file() {
+ assert_not_a_cargo_toml("bench", "foo/bar");
+}
+
+#[test]
+fn build_dir_plus_path() {
+ assert_not_a_cargo_toml("bench", "foo/bar/baz");
+}
+
+#[test]
+fn build_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("build", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn clean_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("clean", "foo");
+}
+
+#[test]
+fn clean_dir_plus_file() {
+ assert_not_a_cargo_toml("clean", "foo/bar");
+}
+
+#[test]
+fn clean_dir_plus_path() {
+ assert_not_a_cargo_toml("clean", "foo/bar/baz");
+}
+
+#[test]
+fn clean_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("clean", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn doc_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("doc", "foo");
+}
+
+#[test]
+fn doc_dir_plus_file() {
+ assert_not_a_cargo_toml("doc", "foo/bar");
+}
+
+#[test]
+fn doc_dir_plus_path() {
+ assert_not_a_cargo_toml("doc", "foo/bar/baz");
+}
+
+#[test]
+fn doc_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("doc", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn fetch_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("fetch", "foo");
+}
+
+#[test]
+fn fetch_dir_plus_file() {
+ assert_not_a_cargo_toml("fetch", "foo/bar");
+}
+
+#[test]
+fn fetch_dir_plus_path() {
+ assert_not_a_cargo_toml("fetch", "foo/bar/baz");
+}
+
+#[test]
+fn fetch_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("fetch", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn generate_lockfile_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("generate-lockfile", "foo");
+}
+
+#[test]
+fn generate_lockfile_dir_plus_file() {
+ assert_not_a_cargo_toml("generate-lockfile", "foo/bar");
+}
+
+#[test]
+fn generate_lockfile_dir_plus_path() {
+ assert_not_a_cargo_toml("generate-lockfile", "foo/bar/baz");
+}
+
+#[test]
+fn generate_lockfile_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("generate-lockfile", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn package_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("package", "foo");
+}
+
+#[test]
+fn package_dir_plus_file() {
+ assert_not_a_cargo_toml("package", "foo/bar");
+}
+
+#[test]
+fn package_dir_plus_path() {
+ assert_not_a_cargo_toml("package", "foo/bar/baz");
+}
+
+#[test]
+fn package_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("package", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn pkgid_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("pkgid", "foo");
+}
+
+#[test]
+fn pkgid_dir_plus_file() {
+ assert_not_a_cargo_toml("pkgid", "foo/bar");
+}
+
+#[test]
+fn pkgid_dir_plus_path() {
+ assert_not_a_cargo_toml("pkgid", "foo/bar/baz");
+}
+
+#[test]
+fn pkgid_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("pkgid", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn publish_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("publish", "foo");
+}
+
+#[test]
+fn publish_dir_plus_file() {
+ assert_not_a_cargo_toml("publish", "foo/bar");
+}
+
+#[test]
+fn publish_dir_plus_path() {
+ assert_not_a_cargo_toml("publish", "foo/bar/baz");
+}
+
+#[test]
+fn publish_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("publish", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn read_manifest_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("read-manifest", "foo");
+}
+
+#[test]
+fn read_manifest_dir_plus_file() {
+ assert_not_a_cargo_toml("read-manifest", "foo/bar");
+}
+
+#[test]
+fn read_manifest_dir_plus_path() {
+ assert_not_a_cargo_toml("read-manifest", "foo/bar/baz");
+}
+
+#[test]
+fn read_manifest_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("read-manifest", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn run_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("run", "foo");
+}
+
+#[test]
+fn run_dir_plus_file() {
+ assert_not_a_cargo_toml("run", "foo/bar");
+}
+
+#[test]
+fn run_dir_plus_path() {
+ assert_not_a_cargo_toml("run", "foo/bar/baz");
+}
+
+#[test]
+fn run_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("run", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn rustc_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("rustc", "foo");
+}
+
+#[test]
+fn rustc_dir_plus_file() {
+ assert_not_a_cargo_toml("rustc", "foo/bar");
+}
+
+#[test]
+fn rustc_dir_plus_path() {
+ assert_not_a_cargo_toml("rustc", "foo/bar/baz");
+}
+
+#[test]
+fn rustc_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("rustc", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn test_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("test", "foo");
+}
+
+#[test]
+fn test_dir_plus_file() {
+ assert_not_a_cargo_toml("test", "foo/bar");
+}
+
+#[test]
+fn test_dir_plus_path() {
+ assert_not_a_cargo_toml("test", "foo/bar/baz");
+}
+
+#[test]
+fn test_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("test", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn update_dir_containing_cargo_toml() {
+ assert_not_a_cargo_toml("update", "foo");
+}
+
+#[test]
+fn update_dir_plus_file() {
+ assert_not_a_cargo_toml("update", "foo/bar");
+}
+
+#[test]
+fn update_dir_plus_path() {
+ assert_not_a_cargo_toml("update", "foo/bar/baz");
+}
+
+#[test]
+fn update_dir_to_nonexistent_cargo_toml() {
+ assert_cargo_toml_doesnt_exist("update", "foo/bar/baz/Cargo.toml");
+}
+
+#[test]
+fn verify_project_dir_containing_cargo_toml() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("verify-project")
+ .arg("--manifest-path").arg("foo")
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(1)
+ .with_stdout("\
+{\"invalid\":\"the manifest-path must be a path to a Cargo.toml file\"}\
+ "));
+}
+
+#[test]
+fn verify_project_dir_plus_file() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("verify-project")
+ .arg("--manifest-path").arg("foo/bar")
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(1)
+ .with_stdout("\
+{\"invalid\":\"the manifest-path must be a path to a Cargo.toml file\"}\
+ "));
+}
+
+#[test]
+fn verify_project_dir_plus_path() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("verify-project")
+ .arg("--manifest-path").arg("foo/bar/baz")
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(1)
+ .with_stdout("\
+{\"invalid\":\"the manifest-path must be a path to a Cargo.toml file\"}\
+ "));
+}
+
+#[test]
+fn verify_project_dir_to_nonexistent_cargo_toml() {
+ let p = project("foo");
+ assert_that(p.cargo_process("verify-project")
+ .arg("--manifest-path").arg("foo/bar/baz/Cargo.toml")
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(1)
+ .with_stdout("\
+{\"invalid\":\"manifest path `foo[..]bar[..]baz[..]Cargo.toml` does not exist\"}\
+ "));
+}
--- /dev/null
+extern crate cargotest;
+extern crate cargo;
+extern crate hamcrest;
+
+use std::str;
+
+use cargo::util::process;
+use cargotest::is_nightly;
+use cargotest::support::paths::CargoPathExt;
+use cargotest::support::{project, execs, basic_bin_manifest, basic_lib_manifest};
+use hamcrest::{assert_that, existing_file};
+
+#[test]
+fn cargo_bench_simple() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", r#"
+ #![feature(test)]
+ extern crate test;
+
+ fn hello() -> &'static str {
+ "hello"
+ }
+
+ pub fn main() {
+ println!("{}", hello())
+ }
+
+ #[bench]
+ fn bench_hello(_b: &mut test::Bencher) {
+ assert_eq!(hello(), "hello")
+ }"#);
+
+ assert_that(p.cargo_process("build"), execs());
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("hello\n"));
+
+ assert_that(p.cargo("bench"),
+ execs().with_stderr(&format!("\
+[COMPILING] foo v0.5.0 ({})
+[RUNNING] target[..]release[..]foo-[..]", p.url()))
+ .with_stdout("
+running 1 test
+test bench_hello ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"));
+}
+
+#[test]
+fn bench_tarname() {
+ if !is_nightly() { return }
+
+ let prj = project("foo")
+ .file("Cargo.toml" , r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("benches/bin1.rs", r#"
+ #![feature(test)]
+ extern crate test;
+ #[bench] fn run1(_ben: &mut test::Bencher) { }"#)
+ .file("benches/bin2.rs", r#"
+ #![feature(test)]
+ extern crate test;
+ #[bench] fn run2(_ben: &mut test::Bencher) { }"#);
+
+ assert_that(prj.cargo_process("bench").arg("--bench").arg("bin2"),
+ execs().with_status(0)
+ .with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] target[..]release[..]bin2[..]
+", dir = prj.url()))
+ .with_stdout("
+running 1 test
+test run2 ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"));
+}
+
+#[test]
+fn cargo_bench_verbose() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", r#"
+ #![feature(test)]
+ extern crate test;
+ fn main() {}
+ #[bench] fn bench_hello(_b: &mut test::Bencher) {}
+ "#);
+
+ assert_that(p.cargo_process("bench").arg("-v").arg("hello"),
+ execs().with_stderr(&format!("\
+[COMPILING] foo v0.5.0 ({url})
+[RUNNING] `rustc src[..]foo.rs [..]`
+[RUNNING] `[..]target[..]release[..]foo-[..] hello --bench`", url = p.url()))
+ .with_stdout("
+running 1 test
+test bench_hello ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"));
+}
+
+#[test]
+fn many_similar_names() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "
+ #![feature(test)]
+ extern crate test;
+ pub fn foo() {}
+ #[bench] fn lib_bench(_b: &mut test::Bencher) {}
+ ")
+ .file("src/main.rs", "
+ #![feature(test)]
+ extern crate foo;
+ extern crate test;
+ fn main() {}
+ #[bench] fn bin_bench(_b: &mut test::Bencher) { foo::foo() }
+ ")
+ .file("benches/foo.rs", r#"
+ #![feature(test)]
+ extern crate foo;
+ extern crate test;
+ #[bench] fn bench_bench(_b: &mut test::Bencher) { foo::foo() }
+ "#);
+
+ let output = p.cargo_process("bench").exec_with_output().unwrap();
+ let output = str::from_utf8(&output.stdout).unwrap();
+ assert!(output.contains("test bin_bench"), "bin_bench missing\n{}", output);
+ assert!(output.contains("test lib_bench"), "lib_bench missing\n{}", output);
+ assert!(output.contains("test bench_bench"), "bench_bench missing\n{}", output);
+}
+
+#[test]
+fn cargo_bench_failing_test() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", r#"
+ #![feature(test)]
+ extern crate test;
+ fn hello() -> &'static str {
+ "hello"
+ }
+
+ pub fn main() {
+ println!("{}", hello())
+ }
+
+ #[bench]
+ fn bench_hello(_b: &mut test::Bencher) {
+ assert_eq!(hello(), "nope")
+ }"#);
+
+ assert_that(p.cargo_process("build"), execs());
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("hello\n"));
+
+ assert_that(p.cargo("bench"),
+ execs().with_stdout_contains("
+running 1 test
+test bench_hello ... ")
+ .with_stderr_contains(format!("\
+[COMPILING] foo v0.5.0 ({})
+[RUNNING] target[..]release[..]foo-[..]
+thread '<main>' panicked at 'assertion failed: \
+ `(left == right)` (left: \
+ `\"hello\"`, right: `\"nope\"`)', src[..]foo.rs:14
+[..]
+", p.url()))
+ .with_status(101));
+}
+
+#[test]
+fn bench_with_lib_dep() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [[bin]]
+ name = "baz"
+ path = "src/main.rs"
+ "#)
+ .file("src/lib.rs", r#"
+ #![feature(test)]
+ extern crate test;
+ ///
+ /// ```rust
+ /// extern crate foo;
+ /// fn main() {
+ /// println!("{}", foo::foo());
+ /// }
+ /// ```
+ ///
+ pub fn foo(){}
+ #[bench] fn lib_bench(_b: &mut test::Bencher) {}
+ "#)
+ .file("src/main.rs", "
+ #![feature(test)]
+ extern crate foo;
+ extern crate test;
+
+ fn main() {}
+
+ #[bench]
+ fn bin_bench(_b: &mut test::Bencher) {}
+ ");
+
+ assert_that(p.cargo_process("bench"),
+ execs().with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({})
+[RUNNING] target[..]release[..]baz-[..]
+[RUNNING] target[..]release[..]foo-[..]", p.url()))
+ .with_stdout("
+running 1 test
+test bin_bench ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+
+running 1 test
+test lib_bench ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"))
+}
+
+#[test]
+fn bench_with_deep_lib_dep() {
+ if !is_nightly() { return }
+
+ let p = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.foo]
+ path = "../foo"
+ "#)
+ .file("src/lib.rs", "
+ #![feature(test)]
+ extern crate foo;
+ extern crate test;
+ #[bench]
+ fn bar_bench(_b: &mut test::Bencher) {
+ foo::foo();
+ }
+ ");
+ let p2 = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "
+ #![feature(test)]
+ extern crate test;
+
+ pub fn foo() {}
+
+ #[bench]
+ fn foo_bench(_b: &mut test::Bencher) {}
+ ");
+
+ p2.build();
+ assert_that(p.cargo_process("bench"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ([..])
+[COMPILING] bar v0.0.1 ({dir})
+[RUNNING] target[..]", dir = p.url()))
+ .with_stdout("
+running 1 test
+test bar_bench ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"));
+}
+
+#[test]
+fn external_bench_explicit() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [[bench]]
+ name = "bench"
+ path = "src/bench.rs"
+ "#)
+ .file("src/lib.rs", r#"
+ #![feature(test)]
+ extern crate test;
+ pub fn get_hello() -> &'static str { "Hello" }
+
+ #[bench]
+ fn internal_bench(_b: &mut test::Bencher) {}
+ "#)
+ .file("src/bench.rs", r#"
+ #![feature(test)]
+ extern crate foo;
+ extern crate test;
+
+ #[bench]
+ fn external_bench(_b: &mut test::Bencher) {}
+ "#);
+
+ assert_that(p.cargo_process("bench"),
+ execs().with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({})
+[RUNNING] target[..]release[..]bench-[..]
+[RUNNING] target[..]release[..]foo-[..]", p.url()))
+ .with_stdout("
+running 1 test
+test external_bench ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+
+running 1 test
+test internal_bench ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"))
+}
+
+#[test]
+fn external_bench_implicit() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ #![feature(test)]
+ extern crate test;
+
+ pub fn get_hello() -> &'static str { "Hello" }
+
+ #[bench]
+ fn internal_bench(_b: &mut test::Bencher) {}
+ "#)
+ .file("benches/external.rs", r#"
+ #![feature(test)]
+ extern crate foo;
+ extern crate test;
+
+ #[bench]
+ fn external_bench(_b: &mut test::Bencher) {}
+ "#);
+
+ assert_that(p.cargo_process("bench"),
+ execs().with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({})
+[RUNNING] target[..]release[..]external-[..]
+[RUNNING] target[..]release[..]foo-[..]", p.url()))
+ .with_stdout("
+running 1 test
+test external_bench ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+
+running 1 test
+test internal_bench ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"))
+}
+
+#[test]
+fn dont_run_examples() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ "#)
+ .file("examples/dont-run-me-i-will-fail.rs", r#"
+ fn main() { panic!("Examples should not be run by 'cargo test'"); }
+ "#);
+ assert_that(p.cargo_process("bench"),
+ execs().with_status(0));
+}
+
+#[test]
+fn pass_through_command_line() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "
+ #![feature(test)]
+ extern crate test;
+
+ #[bench] fn foo(_b: &mut test::Bencher) {}
+ #[bench] fn bar(_b: &mut test::Bencher) {}
+ ");
+
+ assert_that(p.cargo_process("bench").arg("bar"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] target[..]release[..]foo-[..]", dir = p.url()))
+ .with_stdout("
+running 1 test
+test bar ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"));
+
+ assert_that(p.cargo("bench").arg("foo"),
+ execs().with_status(0)
+ .with_stderr("\
+[RUNNING] target[..]release[..]foo-[..]")
+ .with_stdout("
+running 1 test
+test foo ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"));
+}
+
+// Regression test for running cargo-bench twice with
+// tests in an rlib
+#[test]
+fn cargo_bench_twice() {
+ if !is_nightly() { return }
+
+ let p = project("test_twice")
+ .file("Cargo.toml", &basic_lib_manifest("test_twice"))
+ .file("src/test_twice.rs", r#"
+ #![crate_type = "rlib"]
+ #![feature(test)]
+
+ extern crate test;
+
+ #[bench]
+ fn dummy_bench(b: &mut test::Bencher) { }
+ "#);
+
+ p.cargo_process("build");
+
+ for _ in 0..2 {
+ assert_that(p.cargo("bench"),
+ execs().with_status(0));
+ }
+}
+
+#[test]
+fn lib_bin_same_name() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo"
+ [[bin]]
+ name = "foo"
+ "#)
+ .file("src/lib.rs", "
+ #![feature(test)]
+ extern crate test;
+ #[bench] fn lib_bench(_b: &mut test::Bencher) {}
+ ")
+ .file("src/main.rs", "
+ #![feature(test)]
+ extern crate foo;
+ extern crate test;
+
+ #[bench]
+ fn bin_bench(_b: &mut test::Bencher) {}
+ ");
+
+ assert_that(p.cargo_process("bench"),
+ execs().with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({})
+[RUNNING] target[..]release[..]foo-[..]
+[RUNNING] target[..]release[..]foo-[..]", p.url()))
+ .with_stdout("
+running 1 test
+test [..] ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+
+running 1 test
+test [..] ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"))
+}
+
+#[test]
+fn lib_with_standard_name() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "syntax"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "
+ #![feature(test)]
+ extern crate test;
+
+ /// ```
+ /// syntax::foo();
+ /// ```
+ pub fn foo() {}
+
+ #[bench]
+ fn foo_bench(_b: &mut test::Bencher) {}
+ ")
+ .file("benches/bench.rs", "
+ #![feature(test)]
+ extern crate syntax;
+ extern crate test;
+
+ #[bench]
+ fn bench(_b: &mut test::Bencher) { syntax::foo() }
+ ");
+
+ assert_that(p.cargo_process("bench"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] syntax v0.0.1 ({dir})
+[RUNNING] target[..]release[..]bench-[..]
+[RUNNING] target[..]release[..]syntax-[..]", dir = p.url()))
+ .with_stdout("
+running 1 test
+test bench ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+
+running 1 test
+test foo_bench ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"));
+}
+
+#[test]
+fn lib_with_standard_name2() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "syntax"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "syntax"
+ bench = false
+ doctest = false
+ "#)
+ .file("src/lib.rs", "
+ pub fn foo() {}
+ ")
+ .file("src/main.rs", "
+ #![feature(test)]
+ extern crate syntax;
+ extern crate test;
+
+ fn main() {}
+
+ #[bench]
+ fn bench(_b: &mut test::Bencher) { syntax::foo() }
+ ");
+
+ assert_that(p.cargo_process("bench"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] syntax v0.0.1 ({dir})
+[RUNNING] target[..]release[..]syntax-[..]", dir = p.url()))
+ .with_stdout("
+running 1 test
+test bench ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"));
+}
+
+#[test]
+fn bench_dylib() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo"
+ crate_type = ["dylib"]
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/lib.rs", r#"
+ #![feature(test)]
+ extern crate bar as the_bar;
+ extern crate test;
+
+ pub fn bar() { the_bar::baz(); }
+
+ #[bench]
+ fn foo(_b: &mut test::Bencher) {}
+ "#)
+ .file("benches/bench.rs", r#"
+ #![feature(test)]
+ extern crate foo as the_foo;
+ extern crate test;
+
+ #[bench]
+ fn foo(_b: &mut test::Bencher) { the_foo::bar(); }
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "bar"
+ crate_type = ["dylib"]
+ "#)
+ .file("bar/src/lib.rs", "
+ pub fn baz() {}
+ ");
+
+ assert_that(p.cargo_process("bench").arg("-v"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] bar v0.0.1 ({dir}/bar)
+[RUNNING] [..] -C opt-level=3 [..]
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] [..] -C opt-level=3 [..]
+[RUNNING] [..] -C opt-level=3 [..]
+[RUNNING] [..] -C opt-level=3 [..]
+[RUNNING] [..]target[..]release[..]bench-[..]
+[RUNNING] [..]target[..]release[..]foo-[..]", dir = p.url()))
+ .with_stdout("
+running 1 test
+test foo ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+
+running 1 test
+test foo ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"));
+ p.root().move_into_the_past();
+ assert_that(p.cargo("bench").arg("-v"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[FRESH] bar v0.0.1 ({dir}/bar)
+[FRESH] foo v0.0.1 ({dir})
+[RUNNING] [..]target[..]release[..]bench-[..]
+[RUNNING] [..]target[..]release[..]foo-[..]", dir = p.url()))
+ .with_stdout("
+running 1 test
+test foo ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+
+running 1 test
+test foo ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"));
+}
+
+#[test]
+fn bench_twice_with_build_cmd() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("build.rs", "fn main() {}")
+ .file("src/lib.rs", "
+ #![feature(test)]
+ extern crate test;
+ #[bench]
+ fn foo(_b: &mut test::Bencher) {}
+ ");
+
+ assert_that(p.cargo_process("bench"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] target[..]release[..]foo-[..]", dir = p.url()))
+ .with_stdout("
+running 1 test
+test foo ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"));
+
+ assert_that(p.cargo("bench"),
+ execs().with_status(0)
+ .with_stderr("\
+[RUNNING] target[..]release[..]foo-[..]")
+ .with_stdout("
+running 1 test
+test foo ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"));
+}
+
+#[test]
+fn bench_with_examples() {
+ if !is_nightly() { return }
+
+ let p = project("testbench")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "testbench"
+ version = "6.6.6"
+ authors = []
+
+ [[example]]
+ name = "teste1"
+
+ [[bench]]
+ name = "testb1"
+ "#)
+ .file("src/lib.rs", r#"
+ #![feature(test)]
+ extern crate test;
+ #[cfg(test)]
+ use test::Bencher;
+
+ pub fn f1() {
+ println!("f1");
+ }
+
+ pub fn f2() {}
+
+ #[bench]
+ fn bench_bench1(_b: &mut Bencher) {
+ f2();
+ }
+ "#)
+ .file("benches/testb1.rs", "
+ #![feature(test)]
+ extern crate testbench;
+ extern crate test;
+
+ use test::Bencher;
+
+ #[bench]
+ fn bench_bench2(_b: &mut Bencher) {
+ testbench::f2();
+ }
+ ")
+ .file("examples/teste1.rs", r#"
+ extern crate testbench;
+
+ fn main() {
+ println!("example1");
+ testbench::f1();
+ }
+ "#);
+
+ assert_that(p.cargo_process("bench").arg("-v"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] testbench v6.6.6 ({url})
+[RUNNING] `rustc [..]`
+[RUNNING] `rustc [..]`
+[RUNNING] `rustc [..]`
+[RUNNING] `{dir}[..]target[..]release[..]testb1-[..] --bench`
+[RUNNING] `{dir}[..]target[..]release[..]testbench-[..] --bench`",
+ dir = p.root().display(), url = p.url()))
+ .with_stdout("
+running 1 test
+test bench_bench2 ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+
+running 1 test
+test bench_bench1 ... bench: [..] 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+"));
+}
+
+#[test]
+fn test_a_bench() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ authors = []
+ version = "0.1.0"
+
+ [lib]
+ name = "foo"
+ test = false
+ doctest = false
+
+ [[bench]]
+ name = "b"
+ test = true
+ "#)
+ .file("src/lib.rs", "")
+ .file("benches/b.rs", r#"
+ #[test]
+ fn foo() {}
+ "#);
+
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] foo v0.1.0 ([..])
+[RUNNING] target[..]debug[..]b-[..]")
+ .with_stdout("
+running 1 test
+test foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn test_bench_no_run() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ authors = []
+ version = "0.1.0"
+ "#)
+ .file("src/lib.rs", "")
+ .file("benches/bbaz.rs", r#"
+ #![feature(test)]
+
+ extern crate test;
+
+ use test::Bencher;
+
+ #[bench]
+ fn bench_baz(_: &mut Bencher) {}
+ "#);
+
+ assert_that(p.cargo_process("bench").arg("--no-run"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] foo v0.1.0 ([..])
+"));
+}
+
+#[test]
+fn test_bench_multiple_packages() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ authors = []
+ version = "0.1.0"
+
+ [dependencies.bar]
+ path = "../bar"
+
+ [dependencies.baz]
+ path = "../baz"
+ "#)
+ .file("src/lib.rs", "");
+
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "bar"
+ authors = []
+ version = "0.1.0"
+
+ [[bench]]
+ name = "bbar"
+ test = true
+ "#)
+ .file("src/lib.rs", "")
+ .file("benches/bbar.rs", r#"
+ #![feature(test)]
+ extern crate test;
+
+ use test::Bencher;
+
+ #[bench]
+ fn bench_bar(_b: &mut Bencher) {}
+ "#);
+ bar.build();
+
+ let baz = project("baz")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "baz"
+ authors = []
+ version = "0.1.0"
+
+ [[bench]]
+ name = "bbaz"
+ test = true
+ "#)
+ .file("src/lib.rs", "")
+ .file("benches/bbaz.rs", r#"
+ #![feature(test)]
+ extern crate test;
+
+ use test::Bencher;
+
+ #[bench]
+ fn bench_baz(_b: &mut Bencher) {}
+ "#);
+ baz.build();
+
+
+ assert_that(p.cargo_process("bench").arg("-p").arg("bar").arg("-p").arg("baz"),
+ execs().with_status(0)
+ .with_stderr_contains("\
+[RUNNING] target[..]release[..]bbaz-[..]")
+ .with_stdout_contains("
+running 1 test
+test bench_baz ... bench: 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+")
+ .with_stderr_contains("\
+[RUNNING] target[..]release[..]bbar-[..]")
+ .with_stdout_contains("
+running 1 test
+test bench_bar ... bench: 0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+"));
+}
--- /dev/null
+extern crate bufstream;
+extern crate git2;
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::collections::HashSet;
+use std::io::prelude::*;
+use std::net::TcpListener;
+use std::thread;
+
+use bufstream::BufStream;
+use cargotest::support::paths;
+use cargotest::support::{project, execs};
+use hamcrest::assert_that;
+
+// Test that HTTP auth is offered from `credential.helper`
+#[test]
+fn http_auth_offered() {
+ let a = TcpListener::bind("127.0.0.1:0").unwrap();
+ let addr = a.local_addr().unwrap();
+
+ fn headers(rdr: &mut BufRead) -> HashSet<String> {
+ let valid = ["GET", "Authorization", "Accept", "User-Agent"];
+ rdr.lines().map(|s| s.unwrap())
+ .take_while(|s| s.len() > 2)
+ .map(|s| s.trim().to_string())
+ .filter(|s| {
+ valid.iter().any(|prefix| s.starts_with(*prefix))
+ })
+ .collect()
+ }
+
+ let t = thread::spawn(move|| {
+ let mut s = BufStream::new(a.accept().unwrap().0);
+ let req = headers(&mut s);
+ s.write_all(b"\
+ HTTP/1.1 401 Unauthorized\r\n\
+ WWW-Authenticate: Basic realm=\"wheee\"\r\n
+ \r\n\
+ ").unwrap();
+ assert_eq!(req, vec![
+ "GET /foo/bar/info/refs?service=git-upload-pack HTTP/1.1",
+ "Accept: */*",
+ "User-Agent: git/1.0 (libgit2 0.23.0)",
+ ].into_iter().map(|s| s.to_string()).collect());
+ drop(s);
+
+ let mut s = BufStream::new(a.accept().unwrap().0);
+ let req = headers(&mut s);
+ s.write_all(b"\
+ HTTP/1.1 401 Unauthorized\r\n\
+ WWW-Authenticate: Basic realm=\"wheee\"\r\n
+ \r\n\
+ ").unwrap();
+ assert_eq!(req, vec![
+ "GET /foo/bar/info/refs?service=git-upload-pack HTTP/1.1",
+ "Authorization: Basic Zm9vOmJhcg==",
+ "Accept: */*",
+ "User-Agent: git/1.0 (libgit2 0.23.0)",
+ ].into_iter().map(|s| s.to_string()).collect());
+ });
+
+ let script = project("script")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "script"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {
+ println!("username=foo");
+ println!("password=bar");
+ }
+ "#);
+
+ assert_that(script.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+ let script = script.bin("script");
+
+ let config = paths::home().join(".gitconfig");
+ let mut config = git2::Config::open(&config).unwrap();
+ config.set_str("credential.helper",
+ &script.display().to_string()).unwrap();
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ git = "http://127.0.0.1:{}/foo/bar"
+ "#, addr.port()))
+ .file("src/main.rs", "")
+ .file(".cargo/config","\
+ [net]
+ retry = 0
+ ");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr(&format!("\
+[UPDATING] git repository `http://{addr}/foo/bar`
+[ERROR] Unable to update http://{addr}/foo/bar
+
+Caused by:
+ failed to clone into: [..]
+
+Caused by:
+ failed to authenticate when downloading repository
+attempted to find username/password via `credential.helper`, but [..]
+
+To learn more, run the command again with --verbose.
+",
+ addr = addr)));
+
+ t.join().ok().unwrap();
+}
+
+// Boy, sure would be nice to have a TLS implementation in rust!
+#[test]
+fn https_something_happens() {
+ let a = TcpListener::bind("127.0.0.1:0").unwrap();
+ let addr = a.local_addr().unwrap();
+ let t = thread::spawn(move|| {
+ drop(a.accept().unwrap());
+ });
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ git = "https://127.0.0.1:{}/foo/bar"
+ "#, addr.port()))
+ .file("src/main.rs", "")
+ .file(".cargo/config","\
+ [net]
+ retry = 0
+ ");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(101).with_stderr_contains(&format!("\
+[UPDATING] git repository `https://{addr}/foo/bar`
+",
+ addr = addr,
+ ))
+ .with_stderr_contains(&format!("\
+Caused by:
+ {errmsg}
+",
+ errmsg = if cfg!(windows) {
+ "[[..]] failed to send request: [..]\n"
+ } else if cfg!(target_os = "macos") {
+ // OSX is difficult to tests as some builds may use
+ // Security.framework and others may use OpenSSL. In that case let's
+ // just not verify the error message here.
+ "[..]"
+ } else {
+ "[[..]] SSL error: [..]"
+ })));
+
+ t.join().ok().unwrap();
+}
+
+// Boy, sure would be nice to have an SSH implementation in rust!
+#[test]
+fn ssh_something_happens() {
+ let a = TcpListener::bind("127.0.0.1:0").unwrap();
+ let addr = a.local_addr().unwrap();
+ let t = thread::spawn(move|| {
+ drop(a.accept().unwrap());
+ });
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ git = "ssh://127.0.0.1:{}/foo/bar"
+ "#, addr.port()))
+ .file("src/main.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(101).with_stderr_contains(&format!("\
+[UPDATING] git repository `ssh://{addr}/foo/bar`
+",
+ addr = addr,
+ ))
+ .with_stderr_contains("\
+Caused by:
+ [[..]] Failed to start SSH session: Failed getting banner
+"));
+ t.join().ok().unwrap();
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::path::MAIN_SEPARATOR as SEP;
+
+use cargotest::support::{basic_bin_manifest, execs, project, ProjectBuilder};
+use hamcrest::{assert_that};
+
+fn verbose_output_for_lib(p: &ProjectBuilder) -> String {
+ format!("\
+[COMPILING] {name} v{version} ({url})
+[RUNNING] `rustc src{sep}lib.rs --crate-name {name} --crate-type lib -g \
+ --out-dir {dir}{sep}target{sep}debug \
+ --emit=dep-info,link \
+ -L dependency={dir}{sep}target{sep}debug \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps`
+", sep = SEP,
+ dir = p.root().display(), url = p.url(),
+ name = "foo", version = "0.0.1")
+}
+
+#[test]
+fn build_lib_only() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "foo"
+ version = "0.0.1"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("src/lib.rs", r#" "#);
+
+ assert_that(p.cargo_process("build").arg("--lib").arg("-v"),
+ execs()
+ .with_status(0)
+ .with_stderr(verbose_output_for_lib(&p)));
+}
+
+
+#[test]
+fn build_with_no_lib() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#);
+
+ assert_that(p.cargo_process("build").arg("--lib"),
+ execs().with_status(101)
+ .with_stderr("[ERROR] no library targets found"));
+}
+
+#[test]
+fn build_with_relative_cargo_home_path() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "foo"
+ version = "0.0.1"
+ authors = ["wycats@example.com"]
+
+ [dependencies]
+
+ "test-dependency" = { path = "src/test_dependency" }
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("src/test_dependency/src/lib.rs", r#" "#)
+ .file("src/test_dependency/Cargo.toml", r#"
+ [package]
+
+ name = "test-dependency"
+ version = "0.0.1"
+ authors = ["wycats@example.com"]
+ "#);
+
+ assert_that(p.cargo_process("build").env("CARGO_HOME", "./cargo_home/"),
+ execs()
+ .with_status(0));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::fs::{self, File};
+use std::io::prelude::*;
+
+use cargotest::{rustc_host, is_nightly, sleep_ms};
+use cargotest::support::{project, execs};
+use cargotest::support::paths::CargoPathExt;
+use hamcrest::{assert_that, existing_file, existing_dir};
+
+#[test]
+fn custom_build_script_failed() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ build = "build.rs"
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("build.rs", r#"
+ fn main() {
+ std::process::exit(101);
+ }
+ "#);
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(101)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.5.0 ({url})
+[RUNNING] `rustc build.rs --crate-name build_script_build --crate-type bin [..]`
+[RUNNING] `[..]build-script-build[..]`
+[ERROR] failed to run custom build command for `foo v0.5.0 ({url})`
+Process didn't exit successfully: `[..]build[..]build-script-build[..]` \
+ (exit code: 101)",
+url = p.url())));
+}
+
+#[test]
+fn custom_build_env_vars() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [features]
+ bar_feat = ["bar/foo"]
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ build = "build.rs"
+
+ [features]
+ foo = []
+ "#)
+ .file("bar/src/lib.rs", r#"
+ pub fn hello() {}
+ "#);
+
+ let file_content = format!(r#"
+ use std::env;
+ use std::io::prelude::*;
+ use std::path::Path;
+ use std::fs;
+
+ fn main() {{
+ let _target = env::var("TARGET").unwrap();
+ let _ncpus = env::var("NUM_JOBS").unwrap();
+ let _dir = env::var("CARGO_MANIFEST_DIR").unwrap();
+
+ let opt = env::var("OPT_LEVEL").unwrap();
+ assert_eq!(opt, "0");
+
+ let opt = env::var("PROFILE").unwrap();
+ assert_eq!(opt, "debug");
+
+ let debug = env::var("DEBUG").unwrap();
+ assert_eq!(debug, "true");
+
+ let out = env::var("OUT_DIR").unwrap();
+ assert!(out.starts_with(r"{0}"));
+ assert!(fs::metadata(&out).map(|m| m.is_dir()).unwrap_or(false));
+
+ let _host = env::var("HOST").unwrap();
+
+ let _feat = env::var("CARGO_FEATURE_FOO").unwrap();
+ }}
+ "#,
+ p.root().join("target").join("debug").join("build").display());
+
+ let p = p.file("bar/build.rs", &file_content);
+
+
+ assert_that(p.cargo_process("build").arg("--features").arg("bar_feat"),
+ execs().with_status(0));
+}
+
+#[test]
+fn custom_build_script_wrong_rustc_flags() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ build = "build.rs"
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-flags=-aaa -bbb");
+ }
+ "#);
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101)
+ .with_stderr_contains(&format!("\
+[ERROR] Only `-l` and `-L` flags are allowed in build script of `foo v0.5.0 ({})`: \
+`-aaa -bbb`",
+p.url())));
+}
+
+/*
+#[test]
+fn custom_build_script_rustc_flags() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.foo]
+ path = "foo"
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("foo/Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ build = "build.rs"
+ "#)
+ .file("foo/src/lib.rs", r#"
+ "#)
+ .file("foo/build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-flags=-l nonexistinglib -L /dummy/path1 -L /dummy/path2");
+ }
+ "#);
+
+ // TODO: TEST FAILS BECAUSE OF WRONG STDOUT (but otherwise, the build works)
+ assert_that(p.cargo_process("build").arg("--verbose"),
+ execs().with_status(101)
+ .with_stderr(&format!("\
+[COMPILING] bar v0.5.0 ({url})
+[RUNNING] `rustc {dir}{sep}src{sep}lib.rs --crate-name test --crate-type lib -g \
+ -C metadata=[..] \
+ -C extra-filename=-[..] \
+ --out-dir {dir}{sep}target \
+ --emit=dep-info,link \
+ -L {dir}{sep}target \
+ -L {dir}{sep}target{sep}deps`
+", sep = path::SEP,
+dir = p.root().display(),
+url = p.url(),
+)));
+}
+*/
+
+#[test]
+fn links_no_build_cmd() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ links = "a"
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] package `foo v0.5.0 (file://[..])` specifies that it links to `a` but does \
+not have a custom build script
+"));
+}
+
+#[test]
+fn links_duplicates() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ links = "a"
+ build = "build.rs"
+
+ [dependencies.a]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", "")
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ links = "a"
+ build = "build.rs"
+ "#)
+ .file("a/src/lib.rs", "")
+ .file("a/build.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] native library `a` is being linked to by more than one package, and can only be \
+linked to by one package
+
+ [..] v0.5.0 (file://[..])
+ [..] v0.5.0 (file://[..])
+"));
+}
+
+#[test]
+fn overrides_and_links() {
+ let target = rustc_host();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+
+ [dependencies.a]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ use std::env;
+ fn main() {
+ assert_eq!(env::var("DEP_FOO_FOO").ok().expect("FOO missing"),
+ "bar");
+ assert_eq!(env::var("DEP_FOO_BAR").ok().expect("BAR missing"),
+ "baz");
+ }
+ "#)
+ .file(".cargo/config", &format!(r#"
+ [target.{}.foo]
+ rustc-flags = "-L foo -L bar"
+ foo = "bar"
+ bar = "baz"
+ "#, target))
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ links = "foo"
+ build = "build.rs"
+ "#)
+ .file("a/src/lib.rs", "")
+ .file("a/build.rs", "not valid rust code");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0)
+ .with_stderr("\
+[..]
+[..]
+[..]
+[..]
+[..]
+[RUNNING] `rustc [..] --crate-name foo [..] -L foo -L bar[..]`
+"));
+}
+
+#[test]
+fn unused_overrides() {
+ let target = rustc_host();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", "fn main() {}")
+ .file(".cargo/config", &format!(r#"
+ [target.{}.foo]
+ rustc-flags = "-L foo -L bar"
+ foo = "bar"
+ bar = "baz"
+ "#, target));
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn links_passes_env_vars() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+
+ [dependencies.a]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ use std::env;
+ fn main() {
+ assert_eq!(env::var("DEP_FOO_FOO").unwrap(), "bar");
+ assert_eq!(env::var("DEP_FOO_BAR").unwrap(), "baz");
+ }
+ "#)
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ links = "foo"
+ build = "build.rs"
+ "#)
+ .file("a/src/lib.rs", "")
+ .file("a/build.rs", r#"
+ use std::env;
+ fn main() {
+ let lib = env::var("CARGO_MANIFEST_LINKS").unwrap();
+ assert_eq!(lib, "foo");
+
+ println!("cargo:foo=bar");
+ println!("cargo:bar=baz");
+ }
+ "#);
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn only_rerun_build_script() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() {}
+ "#);
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+ p.root().move_into_the_past();
+
+ File::create(&p.root().join("some-new-file")).unwrap();
+ p.root().move_into_the_past();
+
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] foo v0.5.0 (file://[..])
+[RUNNING] `[..]build-script-build[..]`
+[RUNNING] `rustc [..] --crate-name foo [..]`
+"));
+}
+
+#[test]
+fn rebuild_continues_to_pass_env_vars() {
+ let a = project("a")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ links = "foo"
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ use std::time::Duration;
+ fn main() {
+ println!("cargo:foo=bar");
+ println!("cargo:bar=baz");
+ std::thread::sleep(Duration::from_millis(500));
+ }
+ "#);
+ a.build();
+ a.root().move_into_the_past();
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+
+ [dependencies.a]
+ path = '{}'
+ "#, a.root().display()))
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ use std::env;
+ fn main() {
+ assert_eq!(env::var("DEP_FOO_FOO").unwrap(), "bar");
+ assert_eq!(env::var("DEP_FOO_BAR").unwrap(), "baz");
+ }
+ "#);
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+ p.root().move_into_the_past();
+
+ File::create(&p.root().join("some-new-file")).unwrap();
+ p.root().move_into_the_past();
+
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn testing_and_such() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() {}
+ "#);
+
+ println!("build");
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+ p.root().move_into_the_past();
+
+ File::create(&p.root().join("src/lib.rs")).unwrap();
+ p.root().move_into_the_past();
+
+ println!("test");
+ assert_that(p.cargo("test").arg("-vj1"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] foo v0.5.0 (file://[..])
+[RUNNING] `[..]build-script-build[..]`
+[RUNNING] `rustc [..] --crate-name foo [..]`
+[RUNNING] `rustc [..] --crate-name foo [..]`
+[RUNNING] `[..]foo-[..][..]`
+[DOCTEST] foo
+[RUNNING] `rustdoc --test [..]`")
+ .with_stdout("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+
+ println!("doc");
+ assert_that(p.cargo("doc").arg("-v"),
+ execs().with_status(0)
+ .with_stderr("\
+[DOCUMENTING] foo v0.5.0 (file://[..])
+[RUNNING] `rustdoc [..]`
+"));
+
+ File::create(&p.root().join("src/main.rs")).unwrap()
+ .write_all(b"fn main() {}").unwrap();
+ println!("run");
+ assert_that(p.cargo("run"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] foo v0.5.0 (file://[..])
+[RUNNING] `target[..]foo[..]`
+"));
+}
+
+#[test]
+fn propagation_of_l_flags() {
+ let target = rustc_host();
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ [dependencies.a]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ links = "bar"
+ build = "build.rs"
+
+ [dependencies.b]
+ path = "../b"
+ "#)
+ .file("a/src/lib.rs", "")
+ .file("a/build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-flags=-L bar");
+ }
+ "#)
+ .file("b/Cargo.toml", r#"
+ [project]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+ links = "foo"
+ build = "build.rs"
+ "#)
+ .file("b/src/lib.rs", "")
+ .file("b/build.rs", "bad file")
+ .file(".cargo/config", &format!(r#"
+ [target.{}.foo]
+ rustc-flags = "-L foo"
+ "#, target));
+
+ assert_that(p.cargo_process("build").arg("-v").arg("-j1"),
+ execs().with_status(0)
+ .with_stderr_contains("\
+[RUNNING] `rustc [..] --crate-name a [..]-L bar[..]-L foo[..]`
+[COMPILING] foo v0.5.0 (file://[..])
+[RUNNING] `rustc [..] --crate-name foo [..] -L bar -L foo`
+"));
+}
+
+#[test]
+fn propagation_of_l_flags_new() {
+ let target = rustc_host();
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ [dependencies.a]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ links = "bar"
+ build = "build.rs"
+
+ [dependencies.b]
+ path = "../b"
+ "#)
+ .file("a/src/lib.rs", "")
+ .file("a/build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-link-search=bar");
+ }
+ "#)
+ .file("b/Cargo.toml", r#"
+ [project]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+ links = "foo"
+ build = "build.rs"
+ "#)
+ .file("b/src/lib.rs", "")
+ .file("b/build.rs", "bad file")
+ .file(".cargo/config", &format!(r#"
+ [target.{}.foo]
+ rustc-link-search = ["foo"]
+ "#, target));
+
+ assert_that(p.cargo_process("build").arg("-v").arg("-j1"),
+ execs().with_status(0)
+ .with_stderr_contains("\
+[RUNNING] `rustc [..] --crate-name a [..]-L bar[..]-L foo[..]`
+[COMPILING] foo v0.5.0 (file://[..])
+[RUNNING] `rustc [..] --crate-name foo [..] -L bar -L foo`
+"));
+}
+
+#[test]
+fn build_deps_simple() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ [build-dependencies.a]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", "
+ extern crate a;
+ fn main() {}
+ ")
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] a v0.5.0 (file://[..])
+[RUNNING] `rustc [..] --crate-name a [..]`
+[COMPILING] foo v0.5.0 (file://[..])
+[RUNNING] `rustc build.rs [..] --extern a=[..]`
+[RUNNING] `[..]foo-[..]build-script-build[..]`
+[RUNNING] `rustc [..] --crate-name foo [..]`
+"));
+}
+
+#[test]
+fn build_deps_not_for_normal() {
+ let target = rustc_host();
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ [build-dependencies.aaaaa]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "extern crate aaaaa;")
+ .file("build.rs", "
+ extern crate aaaaa;
+ fn main() {}
+ ")
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "aaaaa"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v").arg("--target").arg(&target),
+ execs().with_status(101)
+ .with_stderr_contains("\
+[..]lib.rs[..] error: can't find crate for `aaaaa`[..]
+[..]lib.rs[..] extern crate aaaaa;
+[..] ^~~~~~~~~~~~~~~~~~~
+error: aborting due to previous error
+[ERROR] Could not compile `foo`.
+
+Caused by:
+ Process didn't exit successfully: [..]
+"));
+}
+
+#[test]
+fn build_cmd_with_a_build_cmd() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+
+ [build-dependencies.a]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", "
+ extern crate a;
+ fn main() {}
+ ")
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+
+ [build-dependencies.b]
+ path = "../b"
+ "#)
+ .file("a/src/lib.rs", "")
+ .file("a/build.rs", "extern crate b; fn main() {}")
+ .file("b/Cargo.toml", r#"
+ [project]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("b/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] b v0.5.0 (file://[..])
+[RUNNING] `rustc [..] --crate-name b [..]`
+[COMPILING] a v0.5.0 (file://[..])
+[RUNNING] `rustc a[..]build.rs [..] --extern b=[..]`
+[RUNNING] `[..]a-[..]build-script-build[..]`
+[RUNNING] `rustc [..]lib.rs --crate-name a --crate-type lib -g \
+ -C metadata=[..] -C extra-filename=-[..] \
+ --out-dir [..]target[..]deps --emit=dep-info,link \
+ -L [..]target[..]deps -L [..]target[..]deps`
+[COMPILING] foo v0.5.0 (file://[..])
+[RUNNING] `rustc build.rs --crate-name build_script_build --crate-type bin \
+ -g \
+ --out-dir [..]build[..]foo-[..] --emit=dep-info,link \
+ -L [..]target[..]debug -L [..]target[..]deps \
+ --extern a=[..]liba-[..].rlib`
+[RUNNING] `[..]foo-[..]build-script-build[..]`
+[RUNNING] `rustc [..]lib.rs --crate-name foo --crate-type lib -g \
+ --out-dir [..]target[..]debug --emit=dep-info,link \
+ -L [..]target[..]debug -L [..]target[..]deps`
+"));
+}
+
+#[test]
+fn out_dir_is_preserved() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ use std::env;
+ use std::fs::File;
+ use std::path::Path;
+ fn main() {
+ let out = env::var("OUT_DIR").unwrap();
+ File::create(Path::new(&out).join("foo")).unwrap();
+ }
+ "#);
+
+ // Make the file
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+ p.root().move_into_the_past();
+
+ // Change to asserting that it's there
+ File::create(&p.root().join("build.rs")).unwrap().write_all(br#"
+ use std::env;
+ use std::old_io::File;
+ fn main() {
+ let out = env::var("OUT_DIR").unwrap();
+ File::open(&Path::new(&out).join("foo")).unwrap();
+ }
+ "#).unwrap();
+ p.root().move_into_the_past();
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0));
+
+ // Run a fresh build where file should be preserved
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0));
+
+ // One last time to make sure it's still there.
+ File::create(&p.root().join("foo")).unwrap();
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn output_separate_lines() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-flags=-L foo");
+ println!("cargo:rustc-flags=-l static=foo");
+ }
+ "#);
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(101)
+ .with_stderr_contains("\
+[COMPILING] foo v0.5.0 (file://[..])
+[RUNNING] `rustc build.rs [..]`
+[RUNNING] `[..]foo-[..]build-script-build[..]`
+[RUNNING] `rustc [..] --crate-name foo [..] -L foo -l static=foo`
+[ERROR] could not find native static library [..]
+[ERROR] Could not compile [..]
+"));
+}
+
+#[test]
+fn output_separate_lines_new() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-link-search=foo");
+ println!("cargo:rustc-link-lib=static=foo");
+ }
+ "#);
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(101)
+ .with_stderr_contains("\
+[COMPILING] foo v0.5.0 (file://[..])
+[RUNNING] `rustc build.rs [..]`
+[RUNNING] `[..]foo-[..]build-script-build[..]`
+[RUNNING] `rustc [..] --crate-name foo [..] -L foo -l static=foo`
+[ERROR] could not find native static library [..]
+[ERROR] Could not compile [..]
+"));
+}
+
+#[cfg(not(windows))] // FIXME(#867)
+#[test]
+fn code_generation() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/main.rs", r#"
+ include!(concat!(env!("OUT_DIR"), "/hello.rs"));
+
+ fn main() {
+ println!("{}", message());
+ }
+ "#)
+ .file("build.rs", r#"
+ use std::env;
+ use std::fs::File;
+ use std::io::prelude::*;
+ use std::path::PathBuf;
+
+ fn main() {
+ let dst = PathBuf::from(env::var("OUT_DIR").unwrap());
+ let mut f = File::create(&dst.join("hello.rs")).unwrap();
+ f.write_all(b"
+ pub fn message() -> &'static str {
+ \"Hello, World!\"
+ }
+ ").unwrap();
+ }
+ "#);
+ assert_that(p.cargo_process("run"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] foo v0.5.0 (file://[..])
+[RUNNING] `target[..]foo`")
+ .with_stdout("\
+Hello, World!
+"));
+
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0));
+}
+
+#[test]
+fn release_with_build_script() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() {}
+ "#);
+
+ assert_that(p.cargo_process("build").arg("-v").arg("--release"),
+ execs().with_status(0));
+}
+
+#[test]
+fn build_script_only() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("build.rs", r#"fn main() {}"#);
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ no targets specified in the manifest
+ either src/lib.rs, src/main.rs, a [lib] section, or [[bin]] section must be present"));
+}
+
+#[test]
+fn shared_dep_with_a_build_script() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+
+ [dependencies.a]
+ path = "a"
+
+ [build-dependencies.b]
+ path = "b"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", "fn main() {}")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("a/build.rs", "fn main() {}")
+ .file("a/src/lib.rs", "")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies.a]
+ path = "../a"
+ "#)
+ .file("b/src/lib.rs", "");
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn transitive_dep_host() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+
+ [build-dependencies.b]
+ path = "b"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", "fn main() {}")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ links = "foo"
+ build = "build.rs"
+ "#)
+ .file("a/build.rs", "fn main() {}")
+ .file("a/src/lib.rs", "")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+
+ [lib]
+ name = "b"
+ plugin = true
+
+ [dependencies.a]
+ path = "../a"
+ "#)
+ .file("b/src/lib.rs", "");
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn test_a_lib_with_a_build_command() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", r#"
+ include!(concat!(env!("OUT_DIR"), "/foo.rs"));
+
+ /// ```
+ /// foo::bar();
+ /// ```
+ pub fn bar() {
+ assert_eq!(foo(), 1);
+ }
+ "#)
+ .file("build.rs", r#"
+ use std::env;
+ use std::io::prelude::*;
+ use std::fs::File;
+ use std::path::PathBuf;
+
+ fn main() {
+ let out = PathBuf::from(env::var("OUT_DIR").unwrap());
+ File::create(out.join("foo.rs")).unwrap().write_all(b"
+ fn foo() -> i32 { 1 }
+ ").unwrap();
+ }
+ "#);
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0));
+}
+
+#[test]
+fn test_dev_dep_build_script() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dev-dependencies.a]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("a/build.rs", "fn main() {}")
+ .file("a/src/lib.rs", "");
+
+ assert_that(p.cargo_process("test"), execs().with_status(0));
+}
+
+#[test]
+fn build_script_with_dynamic_native_dependency() {
+ let build = project("builder")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "builder"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "builder"
+ crate-type = ["dylib"]
+ plugin = true
+ "#)
+ .file("src/lib.rs", r#"
+ #[no_mangle]
+ pub extern fn foo() {}
+ "#);
+ assert_that(build.cargo_process("build"),
+ execs().with_status(0));
+
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+
+ [build-dependencies.bar]
+ path = "bar"
+ "#)
+ .file("build.rs", r#"
+ extern crate bar;
+ fn main() { bar::bar() }
+ "#)
+ .file("src/lib.rs", "")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("bar/build.rs", r#"
+ use std::env;
+ use std::path::PathBuf;
+
+ fn main() {
+ let src = PathBuf::from(env::var("SRC").unwrap());
+ println!("cargo:rustc-link-search={}/target/debug",
+ src.display());
+ }
+ "#)
+ .file("bar/src/lib.rs", r#"
+ pub fn bar() {
+ #[cfg_attr(not(target_env = "msvc"), link(name = "builder"))]
+ #[cfg_attr(target_env = "msvc", link(name = "builder.dll"))]
+ extern { fn foo(); }
+ unsafe { foo() }
+ }
+ "#);
+
+ assert_that(foo.cargo_process("build").env("SRC", build.root()),
+ execs().with_status(0));
+}
+
+#[test]
+fn profile_and_opt_level_set_correctly() {
+ let build = project("builder")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "builder"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ use std::env;
+
+ fn main() {
+ assert_eq!(env::var("OPT_LEVEL").unwrap(), "3");
+ assert_eq!(env::var("PROFILE").unwrap(), "release");
+ assert_eq!(env::var("DEBUG").unwrap(), "false");
+ }
+ "#);
+ assert_that(build.cargo_process("bench"),
+ execs().with_status(0));
+}
+
+#[test]
+fn build_script_with_lto() {
+ let build = project("builder")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "builder"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+
+ [profile.dev]
+ lto = true
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() {
+ }
+ "#);
+ assert_that(build.cargo_process("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn test_duplicate_deps() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ build = "build.rs"
+
+ [dependencies.bar]
+ path = "bar"
+
+ [build-dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/main.rs", r#"
+ extern crate bar;
+ fn main() { bar::do_nothing() }
+ "#)
+ .file("build.rs", r#"
+ extern crate bar;
+ fn main() { bar::do_nothing() }
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [project]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "pub fn do_nothing() {}");
+
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+}
+
+#[test]
+fn cfg_feedback() {
+ let build = project("builder")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "builder"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/main.rs", "
+ #[cfg(foo)]
+ fn main() {}
+ ")
+ .file("build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-cfg=foo");
+ }
+ "#);
+ assert_that(build.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn cfg_override() {
+ let target = rustc_host();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ links = "a"
+ build = "build.rs"
+ "#)
+ .file("src/main.rs", "
+ #[cfg(foo)]
+ fn main() {}
+ ")
+ .file("build.rs", "")
+ .file(".cargo/config", &format!(r#"
+ [target.{}.a]
+ rustc-cfg = ["foo"]
+ "#, target));
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn cfg_test() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-cfg=foo");
+ }
+ "#)
+ .file("src/lib.rs", r#"
+ ///
+ /// ```
+ /// extern crate foo;
+ ///
+ /// fn main() {
+ /// foo::foo()
+ /// }
+ /// ```
+ ///
+ #[cfg(foo)]
+ pub fn foo() {}
+
+ #[cfg(foo)]
+ #[test]
+ fn test_foo() {
+ foo()
+ }
+ "#)
+ .file("tests/test.rs", r#"
+ #[cfg(foo)]
+ #[test]
+ fn test_bar() {}
+ "#);
+ assert_that(p.cargo_process("test").arg("-v"),
+ execs().with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] [..] build.rs [..]
+[RUNNING] [..]build-script-build[..]
+[RUNNING] [..] --cfg foo[..]
+[RUNNING] [..] --cfg foo[..]
+[RUNNING] [..] --cfg foo[..]
+[RUNNING] [..]foo-[..]
+[RUNNING] [..]test-[..]
+[DOCTEST] foo
+[RUNNING] [..] --cfg foo[..]", dir = p.url()))
+ .with_stdout("
+running 1 test
+test test_foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test test_bar ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test foo_0 ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn cfg_doc() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-cfg=foo");
+ }
+ "#)
+ .file("src/lib.rs", r#"
+ #[cfg(foo)]
+ pub fn foo() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("bar/build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-cfg=bar");
+ }
+ "#)
+ .file("bar/src/lib.rs", r#"
+ #[cfg(bar)]
+ pub fn bar() {}
+ "#);
+ assert_that(p.cargo_process("doc"),
+ execs().with_status(0));
+ assert_that(&p.root().join("target/doc"), existing_dir());
+ assert_that(&p.root().join("target/doc/foo/fn.foo.html"), existing_file());
+ assert_that(&p.root().join("target/doc/bar/fn.bar.html"), existing_file());
+}
+
+#[test]
+fn cfg_override_test() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ links = "a"
+ "#)
+ .file("build.rs", "")
+ .file(".cargo/config", &format!(r#"
+ [target.{}.a]
+ rustc-cfg = ["foo"]
+ "#, rustc_host()))
+ .file("src/lib.rs", r#"
+ ///
+ /// ```
+ /// extern crate foo;
+ ///
+ /// fn main() {
+ /// foo::foo()
+ /// }
+ /// ```
+ ///
+ #[cfg(foo)]
+ pub fn foo() {}
+
+ #[cfg(foo)]
+ #[test]
+ fn test_foo() {
+ foo()
+ }
+ "#)
+ .file("tests/test.rs", r#"
+ #[cfg(foo)]
+ #[test]
+ fn test_bar() {}
+ "#);
+ assert_that(p.cargo_process("test").arg("-v"),
+ execs().with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] `[..]`
+[RUNNING] `[..]`
+[RUNNING] `[..]`
+[RUNNING] [..]foo-[..]
+[RUNNING] [..]test-[..]
+[DOCTEST] foo
+[RUNNING] [..] --cfg foo[..]", dir = p.url()))
+ .with_stdout("
+running 1 test
+test test_foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test test_bar ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test foo_0 ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn cfg_override_doc() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ links = "a"
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file(".cargo/config", &format!(r#"
+ [target.{target}.a]
+ rustc-cfg = ["foo"]
+ [target.{target}.b]
+ rustc-cfg = ["bar"]
+ "#, target = rustc_host()))
+ .file("build.rs", "")
+ .file("src/lib.rs", r#"
+ #[cfg(foo)]
+ pub fn foo() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ links = "b"
+ "#)
+ .file("bar/build.rs", "")
+ .file("bar/src/lib.rs", r#"
+ #[cfg(bar)]
+ pub fn bar() {}
+ "#) ;
+ assert_that(p.cargo_process("doc"),
+ execs().with_status(0));
+ assert_that(&p.root().join("target/doc"), existing_dir());
+ assert_that(&p.root().join("target/doc/foo/fn.foo.html"), existing_file());
+ assert_that(&p.root().join("target/doc/bar/fn.bar.html"), existing_file());
+}
+
+#[test]
+fn flags_go_into_tests() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ b = { path = "b" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("tests/foo.rs", "")
+ .file("b/Cargo.toml", r#"
+ [project]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+ [dependencies]
+ a = { path = "../a" }
+ "#)
+ .file("b/src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("a/src/lib.rs", "")
+ .file("a/build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-link-search=test");
+ }
+ "#);
+
+ assert_that(p.cargo_process("test").arg("-v").arg("--test=foo"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] a v0.5.0 ([..]
+[RUNNING] `rustc a[..]build.rs [..]`
+[RUNNING] `[..]build-script-build[..]`
+[RUNNING] `rustc a[..]src[..]lib.rs [..] -L test[..]`
+[COMPILING] b v0.5.0 ([..]
+[RUNNING] `rustc b[..]src[..]lib.rs [..] -L test[..]`
+[COMPILING] foo v0.5.0 ([..]
+[RUNNING] `rustc src[..]lib.rs [..] -L test[..]`
+[RUNNING] `rustc tests[..]foo.rs [..] -L test[..]`
+[RUNNING] `[..]foo-[..]`")
+ .with_stdout("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+
+ assert_that(p.cargo("test").arg("-v").arg("-pb").arg("--lib"),
+ execs().with_status(0)
+ .with_stderr("\
+[FRESH] a v0.5.0 ([..]
+[COMPILING] b v0.5.0 ([..]
+[RUNNING] `rustc b[..]src[..]lib.rs [..] -L test[..]`
+[RUNNING] `[..]b-[..]`")
+ .with_stdout("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn diamond_passes_args_only_once() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ a = { path = "a" }
+ b = { path = "b" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("tests/foo.rs", "")
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ [dependencies]
+ b = { path = "../b" }
+ c = { path = "../c" }
+ "#)
+ .file("a/src/lib.rs", "")
+ .file("b/Cargo.toml", r#"
+ [project]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+ [dependencies]
+ c = { path = "../c" }
+ "#)
+ .file("b/src/lib.rs", "")
+ .file("c/Cargo.toml", r#"
+ [project]
+ name = "c"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("c/build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-link-search=native=test");
+ }
+ "#)
+ .file("c/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] c v0.5.0 ([..]
+[RUNNING] `rustc [..]`
+[RUNNING] `[..]`
+[RUNNING] `rustc [..]`
+[COMPILING] b v0.5.0 ([..]
+[RUNNING] `rustc [..]`
+[COMPILING] a v0.5.0 ([..]
+[RUNNING] `rustc [..]`
+[COMPILING] foo v0.5.0 ([..]
+[RUNNING] `[..]rlib -L native=test`
+"));
+}
+
+#[test]
+fn adding_an_override_invalidates() {
+ let target = rustc_host();
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ links = "foo"
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", "")
+ .file("build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-link-search=native=foo");
+ }
+ "#);
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.5.0 ([..]
+[RUNNING] `rustc [..]`
+[RUNNING] `[..]`
+[RUNNING] `rustc [..] -L native=foo`
+"));
+
+ File::create(p.root().join(".cargo/config")).unwrap().write_all(format!("
+ [target.{}.foo]
+ rustc-link-search = [\"native=bar\"]
+ ", target).as_bytes()).unwrap();
+
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.5.0 ([..]
+[RUNNING] `rustc [..] -L native=bar`
+"));
+}
+
+#[test]
+fn changing_an_override_invalidates() {
+ let target = rustc_host();
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ links = "foo"
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", &format!("
+ [target.{}.foo]
+ rustc-link-search = [\"native=foo\"]
+ ", target))
+ .file("build.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.5.0 ([..]
+[RUNNING] `rustc [..] -L native=foo`
+"));
+
+ File::create(p.root().join(".cargo/config")).unwrap().write_all(format!("
+ [target.{}.foo]
+ rustc-link-search = [\"native=bar\"]
+ ", target).as_bytes()).unwrap();
+
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.5.0 ([..]
+[RUNNING] `rustc [..] -L native=bar`
+"));
+}
+
+#[test]
+fn rebuild_only_on_explicit_paths() {
+ let p = project("a")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() {
+ println!("cargo:rerun-if-changed=foo");
+ println!("cargo:rerun-if-changed=bar");
+ }
+ "#);
+ p.build();
+
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0));
+
+ // files don't exist, so should always rerun if they don't exist
+ println!("run without");
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] a v0.5.0 ([..])
+[RUNNING] `[..]build-script-build[..]`
+[RUNNING] `rustc src[..]lib.rs [..]`
+"));
+
+ sleep_ms(1000);
+ File::create(p.root().join("foo")).unwrap();
+ File::create(p.root().join("bar")).unwrap();
+
+ // now the exist, so run once, catch the mtime, then shouldn't run again
+ println!("run with");
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] a v0.5.0 ([..])
+[RUNNING] `[..]build-script-build[..]`
+[RUNNING] `rustc src[..]lib.rs [..]`
+"));
+
+ println!("run with2");
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[FRESH] a v0.5.0 ([..])
+"));
+
+ sleep_ms(1000);
+
+ // random other files do not affect freshness
+ println!("run baz");
+ File::create(p.root().join("baz")).unwrap();
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[FRESH] a v0.5.0 ([..])
+"));
+
+ // but changing dependent files does
+ println!("run foo change");
+ File::create(p.root().join("foo")).unwrap();
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] a v0.5.0 ([..])
+[RUNNING] `[..]build-script-build[..]`
+[RUNNING] `rustc src[..]lib.rs [..]`
+"));
+
+ // .. as does deleting a file
+ println!("run foo delete");
+ fs::remove_file(p.root().join("bar")).unwrap();
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] a v0.5.0 ([..])
+[RUNNING] `[..]build-script-build[..]`
+[RUNNING] `rustc src[..]lib.rs [..]`
+"));
+}
+
+
+#[test]
+fn doctest_recieves_build_link_args() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ [dependencies.a]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ links = "bar"
+ build = "build.rs"
+ "#)
+ .file("a/src/lib.rs", "")
+ .file("a/build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-link-search=native=bar");
+ }
+ "#);
+
+ assert_that(p.cargo_process("test").arg("-v"),
+ execs().with_status(0)
+ .with_stderr_contains("\
+[RUNNING] `rustdoc --test [..] --crate-name foo [..]-L native=bar[..]`
+"));
+}
+
+#[test]
+fn please_respect_the_dag() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+
+ [dependencies]
+ a = { path = 'a' }
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-link-search=native=foo");
+ }
+ "#)
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ links = "bar"
+ build = "build.rs"
+ "#)
+ .file("a/src/lib.rs", "")
+ .file("a/build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-link-search=native=bar");
+ }
+ "#);
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0)
+ .with_stderr_contains("\
+[RUNNING] `rustc [..] -L native=foo -L native=bar[..]`
+"));
+}
+
+#[test]
+fn non_utf8_output() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("build.rs", r#"
+ use std::io::prelude::*;
+
+ fn main() {
+ let mut out = std::io::stdout();
+ // print something that's not utf8
+ out.write_all(b"\xff\xff\n").unwrap();
+
+ // now print some cargo metadata that's utf8
+ println!("cargo:rustc-cfg=foo");
+
+ // now print more non-utf8
+ out.write_all(b"\xff\xff\n").unwrap();
+ }
+ "#)
+ .file("src/main.rs", r#"
+ #[cfg(foo)]
+ fn main() {}
+ "#);
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn custom_target_dir() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ a = { path = "a" }
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", r#"
+ [build]
+ target-dir = 'test'
+ "#)
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("a/build.rs", "fn main() {}")
+ .file("a/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn panic_abort_with_build_scripts() {
+ if !is_nightly() {
+ return
+ }
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [profile.release]
+ panic = 'abort'
+
+ [dependencies]
+ a = { path = "a" }
+ "#)
+ .file("src/lib.rs", "extern crate a;")
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+
+ [build-dependencies]
+ b = { path = "../b" }
+ "#)
+ .file("a/src/lib.rs", "")
+ .file("a/build.rs", "extern crate b; fn main() {}")
+ .file("b/Cargo.toml", r#"
+ [project]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("b/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v").arg("--release"),
+ execs().with_status(0));
+}
--- /dev/null
+extern crate cargo;
+extern crate cargotest;
+extern crate hamcrest;
+extern crate tempdir;
+
+use std::env;
+use std::fs::{self, File};
+use std::io::prelude::*;
+
+use cargo::util::process;
+use cargotest::{is_nightly, rustc_host, sleep_ms};
+use cargotest::support::paths::{CargoPathExt,root};
+use cargotest::support::{ProjectBuilder};
+use cargotest::support::{project, execs, main_file, basic_bin_manifest};
+use hamcrest::{assert_that, existing_file, is_not};
+use tempdir::TempDir;
+
+#[test]
+fn cargo_compile_simple() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("build"), execs());
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("i am foo\n"));
+}
+
+#[test]
+fn cargo_compile_manifest_path() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("build")
+ .arg("--manifest-path").arg("foo/Cargo.toml")
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(0));
+ assert_that(&p.bin("foo"), existing_file());
+}
+
+#[test]
+fn cargo_compile_with_invalid_manifest() {
+ let p = project("foo")
+ .file("Cargo.toml", "");
+
+ assert_that(p.cargo_process("build"),
+ execs()
+ .with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ no `package` or `project` section found.
+"))
+}
+
+#[test]
+fn cargo_compile_with_invalid_manifest2() {
+ let p = project("foo")
+ .file("Cargo.toml", r"
+ [project]
+ foo = bar
+ ");
+
+ assert_that(p.cargo_process("build"),
+ execs()
+ .with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ could not parse input as TOML
+Cargo.toml:3:19-3:20 expected a value
+
+"))
+}
+
+#[test]
+fn cargo_compile_with_invalid_manifest3() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/Cargo.toml", "a = bar");
+
+ assert_that(p.cargo_process("build").arg("--manifest-path")
+ .arg("src/Cargo.toml"),
+ execs()
+ .with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ could not parse input as TOML\n\
+src[..]Cargo.toml:1:5-1:6 expected a value\n\n"))
+}
+
+#[test]
+fn cargo_compile_with_invalid_version() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ authors = []
+ version = "1.0"
+ "#);
+
+ assert_that(p.cargo_process("build"),
+ execs()
+ .with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ cannot parse '1.0' as a semver for the key `project.version`
+"))
+
+}
+
+#[test]
+fn cargo_compile_with_invalid_package_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = ""
+ authors = []
+ version = "0.0.0"
+ "#);
+
+ assert_that(p.cargo_process("build"),
+ execs()
+ .with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ package name cannot be an empty string.
+"))
+}
+
+#[test]
+fn cargo_compile_with_invalid_bin_target_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+
+ [[bin]]
+ name = ""
+ "#);
+
+ assert_that(p.cargo_process("build"),
+ execs()
+ .with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ binary target names cannot be empty.
+"))
+}
+
+#[test]
+fn cargo_compile_with_forbidden_bin_target_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+
+ [[bin]]
+ name = "build"
+ "#);
+
+ assert_that(p.cargo_process("build"),
+ execs()
+ .with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ the binary target name `build` is forbidden
+"))
+}
+
+#[test]
+fn cargo_compile_with_invalid_lib_target_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+
+ [lib]
+ name = ""
+ "#);
+
+ assert_that(p.cargo_process("build"),
+ execs()
+ .with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ library target names cannot be empty.
+"))
+}
+
+#[test]
+fn cargo_compile_without_manifest() {
+ let tmpdir = TempDir::new("cargo").unwrap();
+ let p = ProjectBuilder::new("foo", tmpdir.path().to_path_buf());
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] could not find `Cargo.toml` in `[..]` or any parent directory
+"));
+}
+
+#[test]
+fn cargo_compile_with_invalid_code() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", "invalid rust code!");
+
+ assert_that(p.cargo_process("build"),
+ execs()
+ .with_status(101)
+ .with_stderr_contains("\
+src[..]foo.rs:1:1: 1:8 error: expected item[..]found `invalid`
+src[..]foo.rs:1 invalid rust code!
+ ^~~~~~~
+")
+ .with_stderr_contains("\
+[ERROR] Could not compile `foo`.
+
+To learn more, run the command again with --verbose.\n"));
+ assert_that(&p.root().join("Cargo.lock"), existing_file());
+}
+
+#[test]
+fn cargo_compile_with_invalid_code_in_deps() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "../bar"
+ [dependencies.baz]
+ path = "../baz"
+ "#)
+ .file("src/main.rs", "invalid rust code!");
+ let bar = project("bar")
+ .file("Cargo.toml", &basic_bin_manifest("bar"))
+ .file("src/lib.rs", "invalid rust code!");
+ let baz = project("baz")
+ .file("Cargo.toml", &basic_bin_manifest("baz"))
+ .file("src/lib.rs", "invalid rust code!");
+ bar.build();
+ baz.build();
+ assert_that(p.cargo_process("build"), execs().with_status(101));
+}
+
+#[test]
+fn cargo_compile_with_warnings_in_the_root_package() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", "fn main() {} fn dead() {}");
+
+ assert_that(p.cargo_process("build"),
+ execs()
+ .with_stderr("\
+[COMPILING] foo [..]
+src[..]foo.rs:1:14: 1:26 warning: function is never used: `dead`, \
+ #[warn(dead_code)] on by default
+src[..]foo.rs:1 fn main() {} fn dead() {}
+[..] ^~~~~~~~~~~~
+"));
+}
+
+#[test]
+fn cargo_compile_with_warnings_in_a_dep_package() {
+ let mut p = project("foo");
+
+ p = p
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+ path = "bar"
+
+ [[bin]]
+
+ name = "foo"
+ "#)
+ .file("src/foo.rs",
+ &main_file(r#""{}", bar::gimme()"#, &["bar"]))
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib]
+
+ name = "bar"
+ "#)
+ .file("bar/src/bar.rs", r#"
+ pub fn gimme() -> &'static str {
+ "test passed"
+ }
+
+ fn dead() {}
+ "#);
+
+ assert_that(p.cargo_process("build"),
+ execs().with_stderr(&format!("\
+[COMPILING] bar v0.5.0 ({url}/bar)
+[..]warning: function is never used: `dead`[..]
+[..]fn dead() {{}}
+[..]^~~~~~~~~~~~
+[COMPILING] foo v0.5.0 ({url})
+", url = p.url())));
+
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(
+ process(&p.bin("foo")),
+ execs().with_stdout("test passed\n"));
+}
+
+#[test]
+fn cargo_compile_with_nested_deps_inferred() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+ path = 'bar'
+
+ [[bin]]
+ name = "foo"
+ "#)
+ .file("src/foo.rs",
+ &main_file(r#""{}", bar::gimme()"#, &["bar"]))
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.baz]
+ path = "../baz"
+ "#)
+ .file("bar/src/lib.rs", r#"
+ extern crate baz;
+
+ pub fn gimme() -> String {
+ baz::gimme()
+ }
+ "#)
+ .file("baz/Cargo.toml", r#"
+ [project]
+
+ name = "baz"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("baz/src/lib.rs", r#"
+ pub fn gimme() -> String {
+ "test passed".to_string()
+ }
+ "#);
+
+ p.cargo_process("build")
+ .exec_with_output()
+ .unwrap();
+
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(
+ process(&p.bin("foo")),
+ execs().with_stdout("test passed\n"));
+}
+
+#[test]
+fn cargo_compile_with_nested_deps_correct_bin() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+ path = "bar"
+
+ [[bin]]
+ name = "foo"
+ "#)
+ .file("src/main.rs",
+ &main_file(r#""{}", bar::gimme()"#, &["bar"]))
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.baz]
+ path = "../baz"
+ "#)
+ .file("bar/src/lib.rs", r#"
+ extern crate baz;
+
+ pub fn gimme() -> String {
+ baz::gimme()
+ }
+ "#)
+ .file("baz/Cargo.toml", r#"
+ [project]
+
+ name = "baz"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("baz/src/lib.rs", r#"
+ pub fn gimme() -> String {
+ "test passed".to_string()
+ }
+ "#);
+
+ p.cargo_process("build")
+ .exec_with_output()
+ .unwrap();
+
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(
+ process(&p.bin("foo")),
+ execs().with_stdout("test passed\n"));
+}
+
+#[test]
+fn cargo_compile_with_nested_deps_shorthand() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+ path = "bar"
+
+ [[bin]]
+
+ name = "foo"
+ "#)
+ .file("src/foo.rs",
+ &main_file(r#""{}", bar::gimme()"#, &["bar"]))
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.baz]
+ path = "../baz"
+
+ [lib]
+
+ name = "bar"
+ "#)
+ .file("bar/src/bar.rs", r#"
+ extern crate baz;
+
+ pub fn gimme() -> String {
+ baz::gimme()
+ }
+ "#)
+ .file("baz/Cargo.toml", r#"
+ [project]
+
+ name = "baz"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib]
+
+ name = "baz"
+ "#)
+ .file("baz/src/baz.rs", r#"
+ pub fn gimme() -> String {
+ "test passed".to_string()
+ }
+ "#);
+
+ p.cargo_process("build")
+ .exec_with_output()
+ .unwrap();
+
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(
+ process(&p.bin("foo")),
+ execs().with_stdout("test passed\n"));
+}
+
+#[test]
+fn cargo_compile_with_nested_deps_longhand() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+ path = "bar"
+ version = "0.5.0"
+
+ [[bin]]
+
+ name = "foo"
+ "#)
+ .file("src/foo.rs",
+ &main_file(r#""{}", bar::gimme()"#, &["bar"]))
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.baz]
+ path = "../baz"
+ version = "0.5.0"
+
+ [lib]
+
+ name = "bar"
+ "#)
+ .file("bar/src/bar.rs", r#"
+ extern crate baz;
+
+ pub fn gimme() -> String {
+ baz::gimme()
+ }
+ "#)
+ .file("baz/Cargo.toml", r#"
+ [project]
+
+ name = "baz"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib]
+
+ name = "baz"
+ "#)
+ .file("baz/src/baz.rs", r#"
+ pub fn gimme() -> String {
+ "test passed".to_string()
+ }
+ "#);
+
+ assert_that(p.cargo_process("build"), execs());
+
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("test passed\n"));
+}
+
+// Check that Cargo gives a sensible error if a dependency can't be found
+// because of a name mismatch.
+#[test]
+fn cargo_compile_with_dep_name_mismatch() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "foo"
+ version = "0.0.1"
+ authors = ["wycats@example.com"]
+
+ [[bin]]
+
+ name = "foo"
+
+ [dependencies.notquitebar]
+
+ path = "bar"
+ "#)
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &["bar"]))
+ .file("bar/Cargo.toml", &basic_bin_manifest("bar"))
+ .file("bar/src/bar.rs", &main_file(r#""i am bar""#, &[]));
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr(&format!(
+r#"[ERROR] no matching package named `notquitebar` found (required by `foo`)
+location searched: {proj_dir}/bar
+version required: *
+"#, proj_dir = p.url())));
+}
+
+#[test]
+fn cargo_compile_with_filename() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/bin/a.rs", r#"
+ extern crate foo;
+ fn main() { println!("hello a.rs"); }
+ "#)
+ .file("examples/a.rs", r#"
+ fn main() { println!("example"); }
+ "#);
+
+ assert_that(p.cargo_process("build").arg("--bin").arg("bin.rs"),
+ execs().with_status(101).with_stderr("\
+[ERROR] no bin target named `bin.rs`"));
+
+ assert_that(p.cargo_process("build").arg("--bin").arg("a.rs"),
+ execs().with_status(101).with_stderr("\
+[ERROR] no bin target named `a.rs`
+
+Did you mean `a`?"));
+
+ assert_that(p.cargo_process("build").arg("--example").arg("example.rs"),
+ execs().with_status(101).with_stderr("\
+[ERROR] no example target named `example.rs`"));
+
+ assert_that(p.cargo_process("build").arg("--example").arg("a.rs"),
+ execs().with_status(101).with_stderr("\
+[ERROR] no example target named `a.rs`
+
+Did you mean `a`?"));
+}
+
+#[test]
+fn compile_path_dep_then_change_version() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/lib.rs", "")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+
+ File::create(&p.root().join("bar/Cargo.toml")).unwrap().write_all(br#"
+ [package]
+ name = "bar"
+ version = "0.0.2"
+ authors = []
+ "#).unwrap();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(101).with_stderr("\
+[ERROR] no matching package named `bar` found (required by `foo`)
+location searched: [..]
+version required: = 0.0.1
+versions found: 0.0.2
+consider running `cargo update` to update a path dependency's locked version
+"));
+}
+
+#[test]
+fn ignores_carriage_return_in_lockfile() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("src/main.rs", r#"
+ mod a; fn main() {}
+ "#)
+ .file("src/a.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0));
+
+ let lockfile = p.root().join("Cargo.lock");
+ let mut lock = String::new();
+ File::open(&lockfile).unwrap().read_to_string(&mut lock).unwrap();
+ let lock = lock.replace("\n", "\r\n");
+ File::create(&lockfile).unwrap().write_all(lock.as_bytes()).unwrap();
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn crate_env_vars() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.1-alpha.1"
+ description = "This is foo"
+ homepage = "http://example.com"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/main.rs", r#"
+ extern crate foo;
+
+
+ static VERSION_MAJOR: &'static str = env!("CARGO_PKG_VERSION_MAJOR");
+ static VERSION_MINOR: &'static str = env!("CARGO_PKG_VERSION_MINOR");
+ static VERSION_PATCH: &'static str = env!("CARGO_PKG_VERSION_PATCH");
+ static VERSION_PRE: &'static str = env!("CARGO_PKG_VERSION_PRE");
+ static VERSION: &'static str = env!("CARGO_PKG_VERSION");
+ static CARGO_MANIFEST_DIR: &'static str = env!("CARGO_MANIFEST_DIR");
+ static PKG_NAME: &'static str = env!("CARGO_PKG_NAME");
+ static HOMEPAGE: &'static str = env!("CARGO_PKG_HOMEPAGE");
+ static DESCRIPTION: &'static str = env!("CARGO_PKG_DESCRIPTION");
+
+ fn main() {
+ let s = format!("{}-{}-{} @ {} in {}", VERSION_MAJOR,
+ VERSION_MINOR, VERSION_PATCH, VERSION_PRE,
+ CARGO_MANIFEST_DIR);
+ assert_eq!(s, foo::version());
+ println!("{}", s);
+ assert_eq!("foo", PKG_NAME);
+ assert_eq!("http://example.com", HOMEPAGE);
+ assert_eq!("This is foo", DESCRIPTION);
+ assert_eq!(s, VERSION);
+ }
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn version() -> String {
+ format!("{}-{}-{} @ {} in {}",
+ env!("CARGO_PKG_VERSION_MAJOR"),
+ env!("CARGO_PKG_VERSION_MINOR"),
+ env!("CARGO_PKG_VERSION_PATCH"),
+ env!("CARGO_PKG_VERSION_PRE"),
+ env!("CARGO_MANIFEST_DIR"))
+ }
+ "#);
+
+ println!("build");
+ assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0));
+
+ println!("bin");
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout(&format!("0-5-1 @ alpha.1 in {}\n",
+ p.root().display())));
+
+ println!("test");
+ assert_that(p.cargo("test").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn crate_authors_env_vars() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.1-alpha.1"
+ authors = ["wycats@example.com", "neikos@example.com"]
+ "#)
+ .file("src/main.rs", r#"
+ extern crate foo;
+
+ static AUTHORS: &'static str = env!("CARGO_PKG_AUTHORS");
+
+ fn main() {
+ let s = "wycats@example.com:neikos@example.com";
+ assert_eq!(AUTHORS, foo::authors());
+ println!("{}", AUTHORS);
+ assert_eq!(s, AUTHORS);
+ }
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn authors() -> String {
+ format!("{}", env!("CARGO_PKG_AUTHORS"))
+ }
+ "#);
+
+ println!("build");
+ assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0));
+
+ println!("bin");
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("wycats@example.com:neikos@example.com"));
+
+ println!("test");
+ assert_that(p.cargo("test").arg("-v"),
+ execs().with_status(0));
+}
+
+// this is testing that src/<pkg-name>.rs still works (for now)
+#[test]
+fn many_crate_types_old_style_lib_location() {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib]
+
+ name = "foo"
+ crate_type = ["rlib", "dylib"]
+ "#)
+ .file("src/foo.rs", r#"
+ pub fn foo() {}
+ "#);
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+
+ assert_that(&p.root().join("target/debug/libfoo.rlib"), existing_file());
+ let fname = format!("{}foo{}", env::consts::DLL_PREFIX,
+ env::consts::DLL_SUFFIX);
+ assert_that(&p.root().join("target/debug").join(&fname), existing_file());
+}
+
+#[test]
+fn many_crate_types_correct() {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib]
+
+ name = "foo"
+ crate_type = ["rlib", "dylib"]
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn foo() {}
+ "#);
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0));
+
+ assert_that(&p.root().join("target/debug/libfoo.rlib"), existing_file());
+ let fname = format!("{}foo{}", env::consts::DLL_PREFIX,
+ env::consts::DLL_SUFFIX);
+ assert_that(&p.root().join("target/debug").join(&fname), existing_file());
+}
+
+#[test]
+fn unused_keys() {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ bulid = "foo"
+
+ [lib]
+
+ name = "foo"
+ "#)
+ .file("src/foo.rs", r#"
+ pub fn foo() {}
+ "#);
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0)
+ .with_stderr("\
+warning: unused manifest key: project.bulid
+[COMPILING] foo [..]
+"));
+
+ let mut p = project("bar");
+ p = p
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib]
+
+ name = "foo"
+ build = "foo"
+ "#)
+ .file("src/foo.rs", r#"
+ pub fn foo() {}
+ "#);
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0)
+ .with_stderr("\
+warning: unused manifest key: lib.build
+[COMPILING] foo [..]
+"));
+}
+
+#[test]
+fn self_dependency() {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "test"
+ version = "0.0.0"
+ authors = []
+
+ [dependencies.test]
+
+ path = "."
+
+ [lib]
+
+ name = "test"
+ "#)
+ .file("src/test.rs", "fn main() {}");
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] cyclic package dependency: package `test v0.0.0 ([..])` depends on itself
+"));
+}
+
+#[test]
+fn ignore_broken_symlinks() {
+ // windows and symlinks don't currently agree that well
+ if cfg!(windows) { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
+ .symlink("Notafile", "bar");
+
+ assert_that(p.cargo_process("build"), execs());
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("i am foo\n"));
+}
+
+#[test]
+fn missing_lib_and_bin() {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "test"
+ version = "0.0.0"
+ authors = []
+ "#);
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]Cargo.toml`
+
+Caused by:
+ no targets specified in the manifest
+ either src/lib.rs, src/main.rs, a [lib] section, or [[bin]] section must be present\n"));
+}
+
+#[test]
+fn lto_build() {
+ // FIXME: currently this hits a linker bug on 32-bit MSVC
+ if cfg!(all(target_env = "msvc", target_pointer_width = "32")) {
+ return
+ }
+
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "test"
+ version = "0.0.0"
+ authors = []
+
+ [profile.release]
+ lto = true
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ assert_that(p.cargo_process("build").arg("-v").arg("--release"),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] test v0.0.0 ({url})
+[RUNNING] `rustc src[..]main.rs --crate-name test --crate-type bin \
+ -C opt-level=3 \
+ -C lto \
+ --out-dir {dir}[..]target[..]release \
+ --emit=dep-info,link \
+ -L dependency={dir}[..]target[..]release \
+ -L dependency={dir}[..]target[..]release[..]deps`
+",
+dir = p.root().display(),
+url = p.url(),
+)));
+}
+
+#[test]
+fn verbose_build() {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "test"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "");
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] test v0.0.0 ({url})
+[RUNNING] `rustc src[..]lib.rs --crate-name test --crate-type lib -g \
+ --out-dir {dir}[..]target[..]debug \
+ --emit=dep-info,link \
+ -L dependency={dir}[..]target[..]debug \
+ -L dependency={dir}[..]target[..]debug[..]deps`
+",
+dir = p.root().display(),
+url = p.url(),
+)));
+}
+
+#[test]
+fn verbose_release_build() {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "test"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "");
+ assert_that(p.cargo_process("build").arg("-v").arg("--release"),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] test v0.0.0 ({url})
+[RUNNING] `rustc src[..]lib.rs --crate-name test --crate-type lib \
+ -C opt-level=3 \
+ --out-dir {dir}[..]target[..]release \
+ --emit=dep-info,link \
+ -L dependency={dir}[..]target[..]release \
+ -L dependency={dir}[..]target[..]release[..]deps`
+",
+dir = p.root().display(),
+url = p.url(),
+)));
+}
+
+#[test]
+fn verbose_release_build_deps() {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "test"
+ version = "0.0.0"
+ authors = []
+
+ [dependencies.foo]
+ path = "foo"
+ "#)
+ .file("src/lib.rs", "")
+ .file("foo/Cargo.toml", r#"
+ [package]
+
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+
+ [lib]
+ name = "foo"
+ crate_type = ["dylib", "rlib"]
+ "#)
+ .file("foo/src/lib.rs", "");
+ assert_that(p.cargo_process("build").arg("-v").arg("--release"),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] foo v0.0.0 ({url}/foo)
+[RUNNING] `rustc foo[..]src[..]lib.rs --crate-name foo \
+ --crate-type dylib --crate-type rlib -C prefer-dynamic \
+ -C opt-level=3 \
+ -C metadata=[..] \
+ -C extra-filename=-[..] \
+ --out-dir {dir}[..]target[..]release[..]deps \
+ --emit=dep-info,link \
+ -L dependency={dir}[..]target[..]release[..]deps \
+ -L dependency={dir}[..]target[..]release[..]deps`
+[COMPILING] test v0.0.0 ({url})
+[RUNNING] `rustc src[..]lib.rs --crate-name test --crate-type lib \
+ -C opt-level=3 \
+ --out-dir {dir}[..]target[..]release \
+ --emit=dep-info,link \
+ -L dependency={dir}[..]target[..]release \
+ -L dependency={dir}[..]target[..]release[..]deps \
+ --extern foo={dir}[..]target[..]release[..]deps[..]\
+ {prefix}foo-[..]{suffix} \
+ --extern foo={dir}[..]target[..]release[..]deps[..]libfoo-[..].rlib`
+",
+ dir = p.root().display(),
+ url = p.url(),
+ prefix = env::consts::DLL_PREFIX,
+ suffix = env::consts::DLL_SUFFIX)));
+}
+
+#[test]
+fn explicit_examples() {
+ let mut p = project("world");
+ p = p.file("Cargo.toml", r#"
+ [package]
+ name = "world"
+ version = "1.0.0"
+ authors = []
+
+ [lib]
+ name = "world"
+ path = "src/lib.rs"
+
+ [[example]]
+ name = "hello"
+ path = "examples/ex-hello.rs"
+
+ [[example]]
+ name = "goodbye"
+ path = "examples/ex-goodbye.rs"
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn get_hello() -> &'static str { "Hello" }
+ pub fn get_goodbye() -> &'static str { "Goodbye" }
+ pub fn get_world() -> &'static str { "World" }
+ "#)
+ .file("examples/ex-hello.rs", r#"
+ extern crate world;
+ fn main() { println!("{}, {}!", world::get_hello(), world::get_world()); }
+ "#)
+ .file("examples/ex-goodbye.rs", r#"
+ extern crate world;
+ fn main() { println!("{}, {}!", world::get_goodbye(), world::get_world()); }
+ "#);
+
+ assert_that(p.cargo_process("test").arg("-v"), execs().with_status(0));
+ assert_that(process(&p.bin("examples/hello")),
+ execs().with_stdout("Hello, World!\n"));
+ assert_that(process(&p.bin("examples/goodbye")),
+ execs().with_stdout("Goodbye, World!\n"));
+}
+
+#[test]
+fn implicit_examples() {
+ let mut p = project("world");
+ p = p.file("Cargo.toml", r#"
+ [package]
+ name = "world"
+ version = "1.0.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn get_hello() -> &'static str { "Hello" }
+ pub fn get_goodbye() -> &'static str { "Goodbye" }
+ pub fn get_world() -> &'static str { "World" }
+ "#)
+ .file("examples/hello.rs", r#"
+ extern crate world;
+ fn main() {
+ println!("{}, {}!", world::get_hello(), world::get_world());
+ }
+ "#)
+ .file("examples/goodbye.rs", r#"
+ extern crate world;
+ fn main() {
+ println!("{}, {}!", world::get_goodbye(), world::get_world());
+ }
+ "#);
+
+ assert_that(p.cargo_process("test"), execs().with_status(0));
+ assert_that(process(&p.bin("examples/hello")),
+ execs().with_stdout("Hello, World!\n"));
+ assert_that(process(&p.bin("examples/goodbye")),
+ execs().with_stdout("Goodbye, World!\n"));
+}
+
+#[test]
+fn standard_build_no_ndebug() {
+ let p = project("world")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", r#"
+ fn main() {
+ if cfg!(debug_assertions) {
+ println!("slow")
+ } else {
+ println!("fast")
+ }
+ }
+ "#);
+
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("slow\n"));
+}
+
+#[test]
+fn release_build_ndebug() {
+ let p = project("world")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", r#"
+ fn main() {
+ if cfg!(debug_assertions) {
+ println!("slow")
+ } else {
+ println!("fast")
+ }
+ }
+ "#);
+
+ assert_that(p.cargo_process("build").arg("--release"),
+ execs().with_status(0));
+ assert_that(process(&p.release_bin("foo")),
+ execs().with_stdout("fast\n"));
+}
+
+#[test]
+fn inferred_main_bin() {
+ let p = project("world")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#);
+
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+ assert_that(process(&p.bin("foo")), execs().with_status(0));
+}
+
+#[test]
+fn deletion_causes_failure() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/main.rs", r#"
+ extern crate bar;
+ fn main() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+ let p = p.file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#);
+ assert_that(p.cargo_process("build"), execs().with_status(101));
+}
+
+#[test]
+fn bad_cargo_toml_in_target_dir() {
+ let p = project("world")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("target/Cargo.toml", "bad-toml");
+
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+ assert_that(process(&p.bin("foo")), execs().with_status(0));
+}
+
+#[test]
+fn lib_with_standard_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "syntax"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "
+ pub fn foo() {}
+ ")
+ .file("src/main.rs", "
+ extern crate syntax;
+ fn main() { syntax::foo() }
+ ");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] syntax v0.0.1 ({dir})
+",
+ dir = p.url())));
+}
+
+#[test]
+fn simple_staticlib() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+
+ [lib]
+ name = "foo"
+ crate-type = ["staticlib"]
+ "#)
+ .file("src/lib.rs", "pub fn foo() {}");
+
+ // env var is a test for #1381
+ assert_that(p.cargo_process("build").env("RUST_LOG", "nekoneko=trace"),
+ execs().with_status(0));
+}
+
+#[test]
+fn staticlib_rlib_and_bin() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+
+ [lib]
+ name = "foo"
+ crate-type = ["staticlib", "rlib"]
+ "#)
+ .file("src/lib.rs", "pub fn foo() {}")
+ .file("src/main.rs", r#"
+ extern crate foo;
+
+ fn main() {
+ foo::foo();
+ }"#);
+
+ assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0));
+}
+
+#[test]
+fn opt_out_of_bin() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ bin = []
+
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/main.rs", "bad syntax");
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+}
+
+#[test]
+fn single_lib() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+
+ [lib]
+ name = "foo"
+ path = "src/bar.rs"
+ "#)
+ .file("src/bar.rs", "");
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+}
+
+#[test]
+fn freshness_ignores_excluded() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ build = "build.rs"
+ exclude = ["src/b*.rs"]
+ "#)
+ .file("build.rs", "fn main() {}")
+ .file("src/lib.rs", "pub fn bar() -> i32 { 1 }");
+ foo.build();
+ foo.root().move_into_the_past();
+
+ assert_that(foo.cargo("build"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.0 ({url})
+", url = foo.url())));
+
+ // Smoke test to make sure it doesn't compile again
+ println!("first pass");
+ assert_that(foo.cargo("build"),
+ execs().with_status(0)
+ .with_stdout(""));
+
+ // Modify an ignored file and make sure we don't rebuild
+ println!("second pass");
+ File::create(&foo.root().join("src/bar.rs")).unwrap();
+ assert_that(foo.cargo("build"),
+ execs().with_status(0)
+ .with_stdout(""));
+}
+
+#[test]
+fn rebuild_preserves_out_dir() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ build = 'build.rs'
+ "#)
+ .file("build.rs", r#"
+ use std::env;
+ use std::fs::File;
+ use std::path::Path;
+
+ fn main() {
+ let path = Path::new(&env::var("OUT_DIR").unwrap()).join("foo");
+ if env::var_os("FIRST").is_some() {
+ File::create(&path).unwrap();
+ } else {
+ File::create(&path).unwrap();
+ }
+ }
+ "#)
+ .file("src/lib.rs", "pub fn bar() -> i32 { 1 }");
+ foo.build();
+ foo.root().move_into_the_past();
+
+ assert_that(foo.cargo("build").env("FIRST", "1"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.0 ({url})
+", url = foo.url())));
+
+ File::create(&foo.root().join("src/bar.rs")).unwrap();
+ assert_that(foo.cargo("build"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.0 ({url})
+", url = foo.url())));
+}
+
+#[test]
+fn dep_no_libs() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("bar/src/main.rs", "");
+ assert_that(foo.cargo_process("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn recompile_space_in_name() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+
+ [lib]
+ name = "foo"
+ path = "src/my lib.rs"
+ "#)
+ .file("src/my lib.rs", "");
+ assert_that(foo.cargo_process("build"), execs().with_status(0));
+ foo.root().move_into_the_past();
+ assert_that(foo.cargo("build"),
+ execs().with_status(0).with_stdout(""));
+}
+
+#[cfg(unix)]
+#[test]
+fn ignore_bad_directories() {
+ use std::os::unix::prelude::*;
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "");
+ foo.build();
+ let dir = foo.root().join("tmp");
+ fs::create_dir(&dir).unwrap();
+ let stat = fs::metadata(&dir).unwrap();
+ let mut perms = stat.permissions();
+ perms.set_mode(0o644);
+ fs::set_permissions(&dir, perms.clone()).unwrap();
+ assert_that(foo.cargo("build"),
+ execs().with_status(0));
+ perms.set_mode(0o755);
+ fs::set_permissions(&dir, perms).unwrap();
+}
+
+#[test]
+fn bad_cargo_config() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", r#"
+ this is not valid toml
+ "#);
+ assert_that(foo.cargo_process("build").arg("-v"),
+ execs().with_status(101).with_stderr("\
+[ERROR] Couldn't load Cargo configuration
+
+Caused by:
+ could not parse TOML configuration in `[..]`
+
+Caused by:
+ could not parse input as TOML
+[..].cargo[..]config:2:20-2:21 expected `=`, but found `i`
+
+"));
+}
+
+#[test]
+fn cargo_platform_specific_dependency() {
+ let host = rustc_host();
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ build = "build.rs"
+
+ [target.{host}.dependencies]
+ dep = {{ path = "dep" }}
+ [target.{host}.build-dependencies]
+ build = {{ path = "build" }}
+ [target.{host}.dev-dependencies]
+ dev = {{ path = "dev" }}
+ "#, host = host))
+ .file("src/main.rs", r#"
+ extern crate dep;
+ fn main() { dep::dep() }
+ "#)
+ .file("tests/foo.rs", r#"
+ extern crate dev;
+ #[test]
+ fn foo() { dev::dev() }
+ "#)
+ .file("build.rs", r#"
+ extern crate build;
+ fn main() { build::build(); }
+ "#)
+ .file("dep/Cargo.toml", r#"
+ [project]
+ name = "dep"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("dep/src/lib.rs", "pub fn dep() {}")
+ .file("build/Cargo.toml", r#"
+ [project]
+ name = "build"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("build/src/lib.rs", "pub fn build() {}")
+ .file("dev/Cargo.toml", r#"
+ [project]
+ name = "dev"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("dev/src/lib.rs", "pub fn dev() {}");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0));
+
+ assert_that(&p.bin("foo"), existing_file());
+ assert_that(p.cargo("test"),
+ execs().with_status(0));
+}
+
+#[test]
+fn bad_platform_specific_dependency() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [target.wrong-target.dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/main.rs",
+ &main_file(r#""{}", bar::gimme()"#, &["bar"]))
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("bar/src/lib.rs", r#"
+ extern crate baz;
+
+ pub fn gimme() -> String {
+ format!("")
+ }
+ "#);
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101));
+}
+
+#[test]
+fn cargo_platform_specific_dependency_wrong_platform() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [target.non-existing-triplet.dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("bar/src/lib.rs", r#"
+ invalid rust file, should not be compiled
+ "#);
+
+ p.cargo_process("build").exec_with_output().unwrap();
+
+ assert_that(&p.bin("foo"), existing_file());
+ assert_that(process(&p.bin("foo")),
+ execs());
+
+ let loc = p.root().join("Cargo.lock");
+ let mut lockfile = String::new();
+ File::open(&loc).unwrap().read_to_string(&mut lockfile).unwrap();
+ assert!(lockfile.contains("bar"))
+}
+
+#[test]
+fn example_bin_same_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("examples/foo.rs", "fn main() {}");
+
+ p.cargo_process("test").arg("--no-run").arg("-v")
+ .exec_with_output()
+ .unwrap();
+
+ assert_that(&p.bin("foo"), is_not(existing_file()));
+ assert_that(&p.bin("examples/foo"), existing_file());
+
+ p.cargo("test").arg("--no-run").arg("-v")
+ .exec_with_output()
+ .unwrap();
+
+ assert_that(&p.bin("foo"), is_not(existing_file()));
+ assert_that(&p.bin("examples/foo"), existing_file());
+}
+
+#[test]
+fn compile_then_delete() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("run"), execs().with_status(0));
+ assert_that(&p.bin("foo"), existing_file());
+ if cfg!(windows) {
+ // On windows unlinking immediately after running often fails, so sleep
+ sleep_ms(100);
+ }
+ fs::remove_file(&p.bin("foo")).unwrap();
+ assert_that(p.cargo("run"),
+ execs().with_status(0));
+}
+
+#[test]
+fn transitive_dependencies_not_available() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.aaaaa]
+ path = "a"
+ "#)
+ .file("src/main.rs", "extern crate bbbbb; extern crate aaaaa; fn main() {}")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "aaaaa"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bbbbb]
+ path = "../b"
+ "#)
+ .file("a/src/lib.rs", "extern crate bbbbb;")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "bbbbb"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("b/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(101)
+ .with_stderr_contains("\
+[..] can't find crate for `bbbbb`[..]
+"));
+}
+
+#[test]
+fn cyclic_deps_rejected() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.a]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.foo]
+ path = ".."
+ "#)
+ .file("a/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] cyclic package dependency: package `foo v0.0.1 ([..])` depends on itself
+"));
+}
+
+#[test]
+fn predictable_filenames() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo"
+ crate-type = ["dylib", "rlib"]
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+ assert_that(&p.root().join("target/debug/libfoo.rlib"), existing_file());
+ let dylib_name = format!("{}foo{}", env::consts::DLL_PREFIX,
+ env::consts::DLL_SUFFIX);
+ assert_that(&p.root().join("target/debug").join(dylib_name),
+ existing_file());
+}
+
+#[test]
+fn dashes_to_underscores() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo-bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/main.rs", "extern crate foo_bar; fn main() {}");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+ assert_that(&p.bin("foo-bar"), existing_file());
+}
+
+#[test]
+fn dashes_in_crate_name_bad() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo-bar"
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/main.rs", "extern crate foo_bar; fn main() {}");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(101));
+}
+
+#[test]
+fn rustc_env_var() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo("build")
+ .env("RUSTC", "rustc-that-does-not-exist").arg("-v"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] Could not execute process `rustc-that-does-not-exist -vV` ([..])
+
+Caused by:
+[..]
+"));
+ assert_that(&p.bin("a"), is_not(existing_file()));
+}
+
+#[test]
+fn filtering() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/bin/a.rs", "fn main() {}")
+ .file("src/bin/b.rs", "fn main() {}")
+ .file("examples/a.rs", "fn main() {}")
+ .file("examples/b.rs", "fn main() {}");
+ p.build();
+
+ assert_that(p.cargo("build").arg("--lib"),
+ execs().with_status(0));
+ assert_that(&p.bin("a"), is_not(existing_file()));
+
+ assert_that(p.cargo("build").arg("--bin=a").arg("--example=a"),
+ execs().with_status(0));
+ assert_that(&p.bin("a"), existing_file());
+ assert_that(&p.bin("b"), is_not(existing_file()));
+ assert_that(&p.bin("examples/a"), existing_file());
+ assert_that(&p.bin("examples/b"), is_not(existing_file()));
+}
+
+#[test]
+fn ignore_dotfile() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/bin/.a.rs", "")
+ .file("src/bin/a.rs", "fn main() {}");
+ p.build();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn ignore_dotdirs() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/bin/a.rs", "fn main() {}")
+ .file(".git/Cargo.toml", "")
+ .file(".pc/dummy-fix.patch/Cargo.toml", "");
+ p.build();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn dotdir_root() {
+ let p = ProjectBuilder::new("foo", root().join(".foo"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/bin/a.rs", "fn main() {}");
+ p.build();
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+}
+
+
+#[test]
+fn custom_target_dir() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ let exe_name = format!("foo{}", env::consts::EXE_SUFFIX);
+
+ assert_that(p.cargo("build").env("CARGO_TARGET_DIR", "foo/target"),
+ execs().with_status(0));
+ assert_that(&p.root().join("foo/target/debug").join(&exe_name),
+ existing_file());
+ assert_that(&p.root().join("target/debug").join(&exe_name),
+ is_not(existing_file()));
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+ assert_that(&p.root().join("foo/target/debug").join(&exe_name),
+ existing_file());
+ assert_that(&p.root().join("target/debug").join(&exe_name),
+ existing_file());
+
+ fs::create_dir(p.root().join(".cargo")).unwrap();
+ File::create(p.root().join(".cargo/config")).unwrap().write_all(br#"
+ [build]
+ target-dir = "foo/target"
+ "#).unwrap();
+ assert_that(p.cargo("build").env("CARGO_TARGET_DIR", "bar/target"),
+ execs().with_status(0));
+ assert_that(&p.root().join("bar/target/debug").join(&exe_name),
+ existing_file());
+ assert_that(&p.root().join("foo/target/debug").join(&exe_name),
+ existing_file());
+ assert_that(&p.root().join("target/debug").join(&exe_name),
+ existing_file());
+}
+
+#[test]
+fn rustc_no_trans() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ assert_that(p.cargo("rustc").arg("-v").arg("--").arg("-Zno-trans"),
+ execs().with_status(0));
+}
+
+#[test]
+fn build_multiple_packages() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.d1]
+ path = "d1"
+ [dependencies.d2]
+ path = "d2"
+
+ [[bin]]
+ name = "foo"
+ "#)
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
+ .file("d1/Cargo.toml", r#"
+ [package]
+ name = "d1"
+ version = "0.0.1"
+ authors = []
+
+ [[bin]]
+ name = "d1"
+ "#)
+ .file("d1/src/lib.rs", "")
+ .file("d1/src/main.rs", "fn main() { println!(\"d1\"); }")
+ .file("d2/Cargo.toml", r#"
+ [package]
+ name = "d2"
+ version = "0.0.1"
+ authors = []
+
+ [[bin]]
+ name = "d2"
+ doctest = false
+ "#)
+ .file("d2/src/main.rs", "fn main() { println!(\"d2\"); }");
+ p.build();
+
+ assert_that(p.cargo_process("build").arg("-p").arg("d1").arg("-p").arg("d2")
+ .arg("-p").arg("foo"),
+ execs());
+
+ assert_that(&p.bin("foo"), existing_file());
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("i am foo\n"));
+
+ let d1_path = &p.build_dir().join("debug").join("deps")
+ .join(format!("d1{}", env::consts::EXE_SUFFIX));
+ let d2_path = &p.build_dir().join("debug").join("deps")
+ .join(format!("d2{}", env::consts::EXE_SUFFIX));
+
+ assert_that(d1_path, existing_file());
+ assert_that(process(d1_path), execs().with_stdout("d1"));
+
+ assert_that(d2_path, existing_file());
+ assert_that(process(d2_path),
+ execs().with_stdout("d2"));
+}
+
+#[test]
+fn invalid_spec() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.d1]
+ path = "d1"
+
+ [[bin]]
+ name = "foo"
+ "#)
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
+ .file("d1/Cargo.toml", r#"
+ [package]
+ name = "d1"
+ version = "0.0.1"
+ authors = []
+
+ [[bin]]
+ name = "d1"
+ "#)
+ .file("d1/src/lib.rs", "")
+ .file("d1/src/main.rs", "fn main() { println!(\"d1\"); }");
+ p.build();
+
+ assert_that(p.cargo_process("build").arg("-p").arg("notAValidDep"),
+ execs().with_status(101).with_stderr("\
+[ERROR] package id specification `notAValidDep` matched no packages
+"));
+
+ assert_that(p.cargo_process("build").arg("-p").arg("d1").arg("-p").arg("notAValidDep"),
+ execs().with_status(101).with_stderr("\
+[ERROR] package id specification `notAValidDep` matched no packages
+"));
+}
+
+#[test]
+fn manifest_with_bom_is_ok() {
+ let p = project("foo")
+ .file("Cargo.toml", "\u{FEFF}
+ [package]
+ name = \"foo\"
+ version = \"0.0.1\"
+ authors = []
+ ")
+ .file("src/lib.rs", "");
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn panic_abort_compiles_with_panic_abort() {
+ if !is_nightly() {
+ return
+ }
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [profile.dev]
+ panic = 'abort'
+ "#)
+ .file("src/lib.rs", "");
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0)
+ .with_stderr_contains("[..] -C panic=abort [..]"));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::env;
+use std::ffi::OsString;
+use std::fs::{self, File};
+use std::io::prelude::*;
+use std::path::{Path, PathBuf};
+use std::str;
+
+use cargotest::cargo_process;
+use cargotest::support::paths::{self, CargoPathExt};
+use cargotest::support::{execs, project, ProjectBuilder};
+use hamcrest::{assert_that};
+
+#[cfg_attr(windows,allow(dead_code))]
+enum FakeKind<'a> {
+ Executable,
+ Symlink{target:&'a Path},
+}
+
+/// Add an empty file with executable flags (and platform-dependent suffix).
+/// TODO: move this to `ProjectBuilder` if other cases using this emerge.
+fn fake_file(proj: ProjectBuilder, dir: &Path, name: &str, kind: FakeKind) -> ProjectBuilder {
+ let path = proj.root().join(dir).join(&format!("{}{}", name,
+ env::consts::EXE_SUFFIX));
+ path.parent().unwrap().mkdir_p();
+ match kind {
+ FakeKind::Executable => {
+ File::create(&path).unwrap();
+ make_executable(&path);
+ },
+ FakeKind::Symlink{target} => {
+ make_symlink(&path,target);
+ }
+ }
+ return proj;
+
+ #[cfg(unix)]
+ fn make_executable(p: &Path) {
+ use std::os::unix::prelude::*;
+
+ let mut perms = fs::metadata(p).unwrap().permissions();
+ let mode = perms.mode();
+ perms.set_mode(mode | 0o111);
+ fs::set_permissions(p, perms).unwrap();
+ }
+ #[cfg(windows)]
+ fn make_executable(_: &Path) {}
+ #[cfg(unix)]
+ fn make_symlink(p: &Path, t: &Path) {
+ ::std::os::unix::fs::symlink(t,p).expect("Failed to create symlink");
+ }
+ #[cfg(windows)]
+ fn make_symlink(_: &Path, _: &Path) {
+ panic!("Not supported")
+ }
+}
+
+fn path() -> Vec<PathBuf> {
+ env::split_paths(&env::var_os("PATH").unwrap_or(OsString::new())).collect()
+}
+
+#[test]
+fn list_command_looks_at_path() {
+ let proj = project("list-non-overlapping");
+ let proj = fake_file(proj, &Path::new("path-test"), "cargo-1", FakeKind::Executable);
+ let mut pr = cargo_process();
+
+ let mut path = path();
+ path.push(proj.root().join("path-test"));
+ let path = env::join_paths(path.iter()).unwrap();
+ let output = pr.arg("-v").arg("--list")
+ .env("PATH", &path);
+ let output = output.exec_with_output().unwrap();
+ let output = str::from_utf8(&output.stdout).unwrap();
+ assert!(output.contains("\n 1\n"), "missing 1: {}", output);
+}
+
+// windows and symlinks don't currently agree that well
+#[cfg(unix)]
+#[test]
+fn list_command_resolves_symlinks() {
+ use cargotest::support::cargo_dir;
+
+ let proj = project("list-non-overlapping");
+ let proj = fake_file(proj, &Path::new("path-test"), "cargo-2",
+ FakeKind::Symlink{target:&cargo_dir().join("cargo")});
+ let mut pr = cargo_process();
+
+ let mut path = path();
+ path.push(proj.root().join("path-test"));
+ let path = env::join_paths(path.iter()).unwrap();
+ let output = pr.arg("-v").arg("--list")
+ .env("PATH", &path);
+ let output = output.exec_with_output().unwrap();
+ let output = str::from_utf8(&output.stdout).unwrap();
+ assert!(output.contains("\n 2\n"), "missing 2: {}", output);
+}
+
+#[test]
+fn find_closest_biuld_to_build() {
+ let mut pr = cargo_process();
+ pr.arg("biuld");
+
+ assert_that(pr,
+ execs().with_status(101)
+ .with_stderr("[ERROR] no such subcommand
+
+<tab>Did you mean `build`?
+
+"));
+}
+
+// if a subcommand is more than 3 edit distance away, we don't make a suggestion
+#[test]
+fn find_closest_dont_correct_nonsense() {
+ let mut pr = cargo_process();
+ pr.arg("there-is-no-way-that-there-is-a-command-close-to-this")
+ .cwd(&paths::root());
+
+ assert_that(pr,
+ execs().with_status(101)
+ .with_stderr("[ERROR] no such subcommand
+"));
+}
+
+#[test]
+fn override_cargo_home() {
+ let root = paths::root();
+ let my_home = root.join("my_home");
+ fs::create_dir(&my_home).unwrap();
+ File::create(&my_home.join("config")).unwrap().write_all(br#"
+ [cargo-new]
+ name = "foo"
+ email = "bar"
+ git = false
+ "#).unwrap();
+
+ assert_that(cargo_process()
+ .arg("new").arg("foo")
+ .env("USER", "foo")
+ .env("CARGO_HOME", &my_home),
+ execs().with_status(0));
+
+ let toml = paths::root().join("foo/Cargo.toml");
+ let mut contents = String::new();
+ File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"authors = ["foo <bar>"]"#));
+}
+
+#[test]
+fn cargo_help() {
+ assert_that(cargo_process(),
+ execs().with_status(0));
+ assert_that(cargo_process().arg("help"),
+ execs().with_status(0));
+ assert_that(cargo_process().arg("-h"),
+ execs().with_status(0));
+ assert_that(cargo_process().arg("help").arg("build"),
+ execs().with_status(0));
+ assert_that(cargo_process().arg("build").arg("-h"),
+ execs().with_status(0));
+ assert_that(cargo_process().arg("help").arg("-h"),
+ execs().with_status(0));
+ assert_that(cargo_process().arg("help").arg("help"),
+ execs().with_status(0));
+}
+
+#[test]
+fn explain() {
+ assert_that(cargo_process().arg("--explain").arg("E0001"),
+ execs().with_status(0));
+}
--- /dev/null
+[package]
+name = "cargotest"
+version = "0.1.0"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+bufstream = "0.1"
+cargo = { path = "../.." }
+filetime = "0.1"
+flate2 = "0.2"
+git2 = "0.4"
+hamcrest = "0.1"
+kernel32-sys = "0.2"
+libc = "0.2"
+log = "0.3"
+rustc-serialize = "0.3"
+tar = "0.4"
+tempdir = "0.3"
+term = "0.4.4"
+url = "1.1"
+winapi = "0.2"
--- /dev/null
+use std::fmt;
+use std::path::{PathBuf, Path};
+
+use hamcrest::{Matcher, MatchResult, existing_file};
+use support::paths;
+
+pub use self::InstalledExe as has_installed_exe;
+
+pub fn cargo_home() -> PathBuf {
+ paths::home().join(".cargo")
+}
+
+pub struct InstalledExe(pub &'static str);
+
+fn exe(name: &str) -> String {
+ if cfg!(windows) {format!("{}.exe", name)} else {name.to_string()}
+}
+
+impl<P: AsRef<Path>> Matcher<P> for InstalledExe {
+ fn matches(&self, path: P) -> MatchResult {
+ let path = path.as_ref().join("bin").join(exe(self.0));
+ existing_file().matches(&path)
+ }
+}
+
+impl fmt::Display for InstalledExe {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "installed exe `{}`", self.0)
+ }
+}
--- /dev/null
+#![deny(warnings)]
+
+extern crate bufstream;
+extern crate cargo;
+extern crate filetime;
+extern crate flate2;
+extern crate git2;
+extern crate hamcrest;
+extern crate libc;
+extern crate rustc_serialize;
+extern crate tar;
+extern crate tempdir;
+extern crate term;
+extern crate url;
+#[cfg(windows)] extern crate kernel32;
+#[cfg(windows)] extern crate winapi;
+
+#[macro_use]
+extern crate log;
+
+use cargo::util::Rustc;
+use std::ffi::OsStr;
+use std::time::Duration;
+
+pub mod support;
+pub mod install;
+
+thread_local!(pub static RUSTC: Rustc = Rustc::new("rustc").unwrap());
+
+pub fn rustc_host() -> String {
+ RUSTC.with(|r| r.host.clone())
+}
+
+pub fn is_nightly() -> bool {
+ RUSTC.with(|r| {
+ r.verbose_version.contains("-nightly") ||
+ r.verbose_version.contains("-dev")
+ })
+}
+
+pub fn process<T: AsRef<OsStr>>(t: T) -> cargo::util::ProcessBuilder {
+ let mut p = cargo::util::process(t.as_ref());
+ p.cwd(&support::paths::root())
+ .env_remove("CARGO_HOME")
+ .env("HOME", support::paths::home())
+ .env("CARGO_HOME", support::paths::home().join(".cargo"))
+ .env_remove("RUSTC")
+ .env_remove("RUSTFLAGS")
+ .env_remove("XDG_CONFIG_HOME") // see #2345
+ .env("GIT_CONFIG_NOSYSTEM", "1") // keep trying to sandbox ourselves
+ .env_remove("CARGO_TARGET_DIR") // we assume 'target'
+ .env_remove("MSYSTEM"); // assume cmd.exe everywhere on windows
+ return p
+}
+
+pub fn cargo_process() -> cargo::util::ProcessBuilder {
+ process(&support::cargo_dir().join("cargo"))
+}
+
+pub fn sleep_ms(ms: u64) {
+ std::thread::sleep(Duration::from_millis(ms));
+}
--- /dev/null
+use std::fs::{self, File};
+use std::io::prelude::*;
+use std::path::{Path, PathBuf};
+
+use url::Url;
+use git2;
+
+use cargo::util::ProcessError;
+use support::{ProjectBuilder, project, path2url};
+
+pub struct RepoBuilder {
+ repo: git2::Repository,
+ files: Vec<PathBuf>,
+}
+
+pub fn repo(p: &Path) -> RepoBuilder { RepoBuilder::init(p) }
+
+impl RepoBuilder {
+ pub fn init(p: &Path) -> RepoBuilder {
+ t!(fs::create_dir_all(p.parent().unwrap()));
+ let repo = t!(git2::Repository::init(p));
+ {
+ let mut config = t!(repo.config());
+ t!(config.set_str("user.name", "name"));
+ t!(config.set_str("user.email", "email"));
+ }
+ RepoBuilder { repo: repo, files: Vec::new() }
+ }
+
+ pub fn file(self, path: &str, contents: &str) -> RepoBuilder {
+ let mut me = self.nocommit_file(path, contents);
+ me.files.push(PathBuf::from(path));
+ me
+ }
+
+ pub fn nocommit_file(self, path: &str, contents: &str) -> RepoBuilder {
+ let dst = self.repo.workdir().unwrap().join(path);
+ t!(fs::create_dir_all(dst.parent().unwrap()));
+ t!(t!(File::create(&dst)).write_all(contents.as_bytes()));
+ self
+ }
+
+ pub fn build(&self) {
+ let mut index = t!(self.repo.index());
+ for file in self.files.iter() {
+ t!(index.add_path(file));
+ }
+ t!(index.write());
+ let id = t!(index.write_tree());
+ let tree = t!(self.repo.find_tree(id));
+ let sig = t!(self.repo.signature());
+ t!(self.repo.commit(Some("HEAD"), &sig, &sig,
+ "Initial commit", &tree, &[]));
+ }
+
+ pub fn root(&self) -> &Path {
+ self.repo.workdir().unwrap()
+ }
+
+ pub fn url(&self) -> Url {
+ path2url(self.repo.workdir().unwrap().to_path_buf())
+ }
+}
+
+pub fn new<F>(name: &str, callback: F) -> Result<ProjectBuilder, ProcessError>
+ where F: FnOnce(ProjectBuilder) -> ProjectBuilder
+{
+ let mut git_project = project(name);
+ git_project = callback(git_project);
+ git_project.build();
+
+ let repo = t!(git2::Repository::init(&git_project.root()));
+ let mut cfg = t!(repo.config());
+ t!(cfg.set_str("user.email", "foo@bar.com"));
+ t!(cfg.set_str("user.name", "Foo Bar"));
+ drop(cfg);
+ add(&repo);
+ commit(&repo);
+ Ok(git_project)
+}
+
+pub fn add(repo: &git2::Repository) {
+ // FIXME(libgit2/libgit2#2514): apparently add_all will add all submodules
+ // as well, and then fail b/c they're a directory. As a stopgap, we just
+ // ignore all submodules.
+ let mut s = t!(repo.submodules());
+ for submodule in s.iter_mut() {
+ t!(submodule.add_to_index(false));
+ }
+ let mut index = t!(repo.index());
+ t!(index.add_all(["*"].iter(), git2::ADD_DEFAULT,
+ Some(&mut (|a, _b| {
+ if s.iter().any(|s| a.starts_with(s.path())) {1} else {0}
+ }))));
+ t!(index.write());
+}
+
+pub fn add_submodule<'a>(repo: &'a git2::Repository, url: &str,
+ path: &Path) -> git2::Submodule<'a>
+{
+ let path = path.to_str().unwrap().replace(r"\", "/");
+ let mut s = t!(repo.submodule(url, Path::new(&path), false));
+ let subrepo = t!(s.open());
+ t!(subrepo.remote_add_fetch("origin", "refs/heads/*:refs/heads/*"));
+ let mut origin = t!(subrepo.find_remote("origin"));
+ t!(origin.fetch(&[], None, None));
+ t!(subrepo.checkout_head(None));
+ t!(s.add_finalize());
+ return s;
+}
+
+pub fn commit(repo: &git2::Repository) -> git2::Oid {
+ let tree_id = t!(t!(repo.index()).write_tree());
+ let sig = t!(repo.signature());
+ let mut parents = Vec::new();
+ match repo.head().ok().map(|h| h.target().unwrap()) {
+ Some(parent) => parents.push(t!(repo.find_commit(parent))),
+ None => {}
+ }
+ let parents = parents.iter().collect::<Vec<_>>();
+ t!(repo.commit(Some("HEAD"), &sig, &sig, "test",
+ &t!(repo.find_tree(tree_id)),
+ &parents))
+}
+
+pub fn tag(repo: &git2::Repository, name: &str) {
+ let head = repo.head().unwrap().target().unwrap();
+ t!(repo.tag(name,
+ &t!(repo.find_object(head, None)),
+ &t!(repo.signature()),
+ "make a new tag",
+ false));
+}
--- /dev/null
+use std::env;
+use std::error::Error;
+use std::ffi::OsStr;
+use std::fmt;
+use std::fs;
+use std::io::prelude::*;
+use std::os;
+use std::path::{Path, PathBuf};
+use std::process::Output;
+use std::str;
+use std::usize;
+
+use rustc_serialize::json::Json;
+use url::Url;
+use hamcrest as ham;
+use cargo::util::ProcessBuilder;
+use cargo::util::ProcessError;
+use cargo::util::process;
+
+use support::paths::CargoPathExt;
+
+#[macro_export]
+macro_rules! t {
+ ($e:expr) => (match $e {
+ Ok(e) => e,
+ Err(e) => panic!("{} failed with {}", stringify!($e), e),
+ })
+}
+
+pub mod paths;
+pub mod git;
+pub mod registry;
+
+/*
+ *
+ * ===== Builders =====
+ *
+ */
+
+#[derive(PartialEq,Clone)]
+struct FileBuilder {
+ path: PathBuf,
+ body: String
+}
+
+impl FileBuilder {
+ pub fn new(path: PathBuf, body: &str) -> FileBuilder {
+ FileBuilder { path: path, body: body.to_string() }
+ }
+
+ fn mk(&self) {
+ self.dirname().mkdir_p();
+
+ let mut file = fs::File::create(&self.path).unwrap_or_else(|e| {
+ panic!("could not create file {}: {}", self.path.display(), e)
+ });
+
+ t!(file.write_all(self.body.as_bytes()));
+ }
+
+ fn dirname(&self) -> &Path {
+ self.path.parent().unwrap()
+ }
+}
+
+#[derive(PartialEq,Clone)]
+struct SymlinkBuilder {
+ dst: PathBuf,
+ src: PathBuf,
+}
+
+impl SymlinkBuilder {
+ pub fn new(dst: PathBuf, src: PathBuf) -> SymlinkBuilder {
+ SymlinkBuilder { dst: dst, src: src }
+ }
+
+ #[cfg(unix)]
+ fn mk(&self) {
+ self.dirname().mkdir_p();
+ t!(os::unix::fs::symlink(&self.dst, &self.src));
+ }
+
+ #[cfg(windows)]
+ fn mk(&self) {
+ self.dirname().mkdir_p();
+ t!(os::windows::fs::symlink_file(&self.dst, &self.src));
+ }
+
+ fn dirname(&self) -> &Path {
+ self.src.parent().unwrap()
+ }
+}
+
+#[derive(PartialEq,Clone)]
+pub struct ProjectBuilder {
+ name: String,
+ root: PathBuf,
+ files: Vec<FileBuilder>,
+ symlinks: Vec<SymlinkBuilder>
+}
+
+impl ProjectBuilder {
+ pub fn new(name: &str, root: PathBuf) -> ProjectBuilder {
+ ProjectBuilder {
+ name: name.to_string(),
+ root: root,
+ files: vec![],
+ symlinks: vec![]
+ }
+ }
+
+ pub fn root(&self) -> PathBuf {
+ self.root.clone()
+ }
+
+ pub fn url(&self) -> Url { path2url(self.root()) }
+
+ pub fn bin(&self, b: &str) -> PathBuf {
+ self.build_dir().join("debug").join(&format!("{}{}", b,
+ env::consts::EXE_SUFFIX))
+ }
+
+ pub fn release_bin(&self, b: &str) -> PathBuf {
+ self.build_dir().join("release").join(&format!("{}{}", b,
+ env::consts::EXE_SUFFIX))
+ }
+
+ pub fn target_bin(&self, target: &str, b: &str) -> PathBuf {
+ self.build_dir().join(target).join("debug")
+ .join(&format!("{}{}", b, env::consts::EXE_SUFFIX))
+ }
+
+ pub fn build_dir(&self) -> PathBuf {
+ self.root.join("target")
+ }
+
+ pub fn process<T: AsRef<OsStr>>(&self, program: T) -> ProcessBuilder {
+ let mut p = ::process(program);
+ p.cwd(self.root());
+ return p
+ }
+
+ pub fn cargo(&self, cmd: &str) -> ProcessBuilder {
+ let mut p = self.process(&cargo_dir().join("cargo"));
+ p.arg(cmd);
+ return p;
+ }
+
+ pub fn cargo_process(&self, cmd: &str) -> ProcessBuilder {
+ self.build();
+ self.cargo(cmd)
+ }
+
+ pub fn file<B: AsRef<Path>>(mut self, path: B,
+ body: &str) -> ProjectBuilder {
+ self.files.push(FileBuilder::new(self.root.join(path), body));
+ self
+ }
+
+ pub fn symlink<T: AsRef<Path>>(mut self, dst: T,
+ src: T) -> ProjectBuilder {
+ self.symlinks.push(SymlinkBuilder::new(self.root.join(dst),
+ self.root.join(src)));
+ self
+ }
+
+ // TODO: return something different than a ProjectBuilder
+ pub fn build(&self) -> &ProjectBuilder {
+ // First, clean the directory if it already exists
+ self.rm_root();
+
+ // Create the empty directory
+ self.root.mkdir_p();
+
+ for file in self.files.iter() {
+ file.mk();
+ }
+
+ for symlink in self.symlinks.iter() {
+ symlink.mk();
+ }
+ self
+ }
+
+ fn rm_root(&self) {
+ self.root.rm_rf()
+ }
+}
+
+// Generates a project layout
+pub fn project(name: &str) -> ProjectBuilder {
+ ProjectBuilder::new(name, paths::root().join(name))
+}
+
+// === Helpers ===
+
+pub fn main_file(println: &str, deps: &[&str]) -> String {
+ let mut buf = String::new();
+
+ for dep in deps.iter() {
+ buf.push_str(&format!("extern crate {};\n", dep));
+ }
+
+ buf.push_str("fn main() { println!(");
+ buf.push_str(&println);
+ buf.push_str("); }\n");
+
+ buf.to_string()
+}
+
+trait ErrMsg<T> {
+ fn with_err_msg(self, val: String) -> Result<T, String>;
+}
+
+impl<T, E: fmt::Display> ErrMsg<T> for Result<T, E> {
+ fn with_err_msg(self, val: String) -> Result<T, String> {
+ match self {
+ Ok(val) => Ok(val),
+ Err(err) => Err(format!("{}; original={}", val, err))
+ }
+ }
+}
+
+// Path to cargo executables
+pub fn cargo_dir() -> PathBuf {
+ env::var_os("CARGO_BIN_PATH").map(PathBuf::from).or_else(|| {
+ env::current_exe().ok().as_ref().and_then(|s| s.parent())
+ .map(|s| s.to_path_buf())
+ }).unwrap_or_else(|| {
+ panic!("CARGO_BIN_PATH wasn't set. Cannot continue running test")
+ })
+}
+
+/// Returns an absolute path in the filesystem that `path` points to. The
+/// returned path does not contain any symlinks in its hierarchy.
+/*
+ *
+ * ===== Matchers =====
+ *
+ */
+
+#[derive(Clone)]
+pub struct Execs {
+ expect_stdout: Option<String>,
+ expect_stdin: Option<String>,
+ expect_stderr: Option<String>,
+ expect_exit_code: Option<i32>,
+ expect_stdout_contains: Vec<String>,
+ expect_stderr_contains: Vec<String>,
+ expect_json: Option<Json>,
+}
+
+impl Execs {
+ pub fn with_stdout<S: ToString>(mut self, expected: S) -> Execs {
+ self.expect_stdout = Some(expected.to_string());
+ self
+ }
+
+ pub fn with_stderr<S: ToString>(mut self, expected: S) -> Execs {
+ self.expect_stderr = Some(expected.to_string());
+ self
+ }
+
+ pub fn with_status(mut self, expected: i32) -> Execs {
+ self.expect_exit_code = Some(expected);
+ self
+ }
+
+ pub fn with_stdout_contains<S: ToString>(mut self, expected: S) -> Execs {
+ self.expect_stdout_contains.push(expected.to_string());
+ self
+ }
+
+ pub fn with_stderr_contains<S: ToString>(mut self, expected: S) -> Execs {
+ self.expect_stderr_contains.push(expected.to_string());
+ self
+ }
+
+ pub fn with_json(mut self, expected: &str) -> Execs {
+ self.expect_json = Some(Json::from_str(expected).unwrap());
+ self
+ }
+
+ fn match_output(&self, actual: &Output) -> ham::MatchResult {
+ self.match_status(actual)
+ .and(self.match_stdout(actual))
+ .and(self.match_stderr(actual))
+ }
+
+ fn match_status(&self, actual: &Output) -> ham::MatchResult {
+ match self.expect_exit_code {
+ None => ham::success(),
+ Some(code) => {
+ ham::expect(
+ actual.status.code() == Some(code),
+ format!("exited with {}\n--- stdout\n{}\n--- stderr\n{}",
+ actual.status,
+ String::from_utf8_lossy(&actual.stdout),
+ String::from_utf8_lossy(&actual.stderr)))
+ }
+ }
+ }
+
+ fn match_stdout(&self, actual: &Output) -> ham::MatchResult {
+ try!(self.match_std(self.expect_stdout.as_ref(), &actual.stdout,
+ "stdout", &actual.stderr, false));
+ for expect in self.expect_stdout_contains.iter() {
+ try!(self.match_std(Some(expect), &actual.stdout, "stdout",
+ &actual.stderr, true));
+ }
+ for expect in self.expect_stderr_contains.iter() {
+ try!(self.match_std(Some(expect), &actual.stderr, "stderr",
+ &actual.stdout, true));
+ }
+
+ if let Some(ref expect_json) = self.expect_json {
+ try!(self.match_json(expect_json, &actual.stdout));
+ }
+ Ok(())
+ }
+
+ fn match_stderr(&self, actual: &Output) -> ham::MatchResult {
+ self.match_std(self.expect_stderr.as_ref(), &actual.stderr,
+ "stderr", &actual.stdout, false)
+ }
+
+ fn match_std(&self, expected: Option<&String>, actual: &[u8],
+ description: &str, extra: &[u8],
+ partial: bool) -> ham::MatchResult {
+ let out = match expected {
+ Some(out) => substitute_macros(out),
+ None => return ham::success(),
+ };
+ let actual = match str::from_utf8(actual) {
+ Err(..) => return Err(format!("{} was not utf8 encoded",
+ description)),
+ Ok(actual) => actual,
+ };
+ // Let's not deal with \r\n vs \n on windows...
+ let actual = actual.replace("\r", "");
+ let actual = actual.replace("\t", "<tab>");
+
+ let mut a = actual.lines();
+ let e = out.lines();
+
+ let diffs = if partial {
+ let mut min = self.diff_lines(a.clone(), e.clone(), partial);
+ while let Some(..) = a.next() {
+ let a = self.diff_lines(a.clone(), e.clone(), partial);
+ if a.len() < min.len() {
+ min = a;
+ }
+ }
+ min
+ } else {
+ self.diff_lines(a, e, partial)
+ };
+ ham::expect(diffs.is_empty(),
+ format!("differences:\n\
+ {}\n\n\
+ other output:\n\
+ `{}`", diffs.join("\n"),
+ String::from_utf8_lossy(extra)))
+
+ }
+
+ fn match_json(&self, expected: &Json, stdout: &[u8]) -> ham::MatchResult {
+ let stdout = match str::from_utf8(stdout) {
+ Err(..) => return Err("stdout was not utf8 encoded".to_owned()),
+ Ok(stdout) => stdout,
+ };
+
+ let actual = match Json::from_str(stdout) {
+ Err(..) => return Err(format!("Invalid json {}", stdout)),
+ Ok(actual) => actual,
+ };
+
+ match find_mismatch(expected, &actual) {
+ Some((expected_part, actual_part)) => Err(format!(
+ "JSON mismatch\nExpected:\n{}\nWas:\n{}\nExpected part:\n{}\nActual part:\n{}\n",
+ expected.pretty(), actual.pretty(),
+ expected_part.pretty(), actual_part.pretty()
+ )),
+ None => Ok(()),
+ }
+ }
+
+ fn diff_lines<'a>(&self, actual: str::Lines<'a>, expected: str::Lines<'a>,
+ partial: bool) -> Vec<String> {
+ let actual = actual.take(if partial {
+ expected.clone().count()
+ } else {
+ usize::MAX
+ });
+ zip_all(actual, expected).enumerate().filter_map(|(i, (a,e))| {
+ match (a, e) {
+ (Some(a), Some(e)) => {
+ if lines_match(&e, &a) {
+ None
+ } else {
+ Some(format!("{:3} - |{}|\n + |{}|\n", i, e, a))
+ }
+ },
+ (Some(a), None) => {
+ Some(format!("{:3} -\n + |{}|\n", i, a))
+ },
+ (None, Some(e)) => {
+ Some(format!("{:3} - |{}|\n +\n", i, e))
+ },
+ (None, None) => panic!("Cannot get here")
+ }
+ }).collect()
+ }
+}
+
+fn lines_match(expected: &str, mut actual: &str) -> bool {
+ for (i, part) in expected.split("[..]").enumerate() {
+ match actual.find(part) {
+ Some(j) => {
+ if i == 0 && j != 0 {
+ return false
+ }
+ actual = &actual[j + part.len()..];
+ }
+ None => {
+ return false
+ }
+ }
+ }
+ actual.is_empty() || expected.ends_with("[..]")
+}
+
+#[test]
+fn lines_match_works() {
+ assert!(lines_match("a b", "a b"));
+ assert!(lines_match("a[..]b", "a b"));
+ assert!(lines_match("a[..]", "a b"));
+ assert!(lines_match("[..]", "a b"));
+ assert!(lines_match("[..]b", "a b"));
+
+ assert!(!lines_match("[..]b", "c"));
+ assert!(!lines_match("b", "c"));
+ assert!(!lines_match("b", "cb"));
+}
+
+// Compares JSON object for approximate equality.
+// You can use `[..]` wildcard in strings (useful for OS dependent things such as paths).
+// Arrays are sorted before comparison.
+fn find_mismatch<'a>(expected: &'a Json, actual: &'a Json) -> Option<(&'a Json, &'a Json)> {
+ use rustc_serialize::json::Json::*;
+ match (expected, actual) {
+ (&I64(l), &I64(r)) if l == r => None,
+ (&F64(l), &F64(r)) if l == r => None,
+ (&U64(l), &U64(r)) if l == r => None,
+ (&Boolean(l), &Boolean(r)) if l == r => None,
+ (&String(ref l), &String(ref r)) if lines_match(l, r) => None,
+ (&Array(ref l), &Array(ref r)) => {
+ if l.len() != r.len() {
+ return Some((expected, actual));
+ }
+
+ fn sorted(xs: &Vec<Json>) -> Vec<&Json> {
+ let mut result = xs.iter().collect::<Vec<_>>();
+ // `unwrap` should be safe because JSON spec does not allow NaNs
+ result.sort_by(|x, y| x.partial_cmp(y).unwrap());
+ result
+ }
+
+ sorted(l).iter().zip(sorted(r))
+ .filter_map(|(l, r)| find_mismatch(l, r))
+ .nth(0)
+ }
+ (&Object(ref l), &Object(ref r)) => {
+ let same_keys = l.len() == r.len() && l.keys().all(|k| r.contains_key(k));
+ if !same_keys {
+ return Some((expected, actual));
+ }
+
+ l.values().zip(r.values())
+ .filter_map(|(l, r)| find_mismatch(l, r))
+ .nth(0)
+ }
+ (&Null, &Null) => None,
+ _ => Some((expected, actual)),
+ }
+
+}
+
+struct ZipAll<I1: Iterator, I2: Iterator> {
+ first: I1,
+ second: I2,
+}
+
+impl<T, I1: Iterator<Item=T>, I2: Iterator<Item=T>> Iterator for ZipAll<I1, I2> {
+ type Item = (Option<T>, Option<T>);
+ fn next(&mut self) -> Option<(Option<T>, Option<T>)> {
+ let first = self.first.next();
+ let second = self.second.next();
+
+ match (first, second) {
+ (None, None) => None,
+ (a, b) => Some((a, b))
+ }
+ }
+}
+
+fn zip_all<T, I1: Iterator<Item=T>, I2: Iterator<Item=T>>(a: I1, b: I2) -> ZipAll<I1, I2> {
+ ZipAll {
+ first: a,
+ second: b,
+ }
+}
+
+impl fmt::Display for Execs {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "execs")
+ }
+}
+
+impl ham::Matcher<ProcessBuilder> for Execs {
+ fn matches(&self, mut process: ProcessBuilder) -> ham::MatchResult {
+ self.matches(&mut process)
+ }
+}
+
+impl<'a> ham::Matcher<&'a mut ProcessBuilder> for Execs {
+ fn matches(&self, process: &'a mut ProcessBuilder) -> ham::MatchResult {
+ let res = process.exec_with_output();
+
+ match res {
+ Ok(out) => self.match_output(&out),
+ Err(ProcessError { output: Some(ref out), .. }) => {
+ self.match_output(out)
+ }
+ Err(e) => {
+ let mut s = format!("could not exec process {}: {}", process, e);
+ match e.cause() {
+ Some(cause) => s.push_str(&format!("\ncaused by: {}",
+ cause.description())),
+ None => {}
+ }
+ Err(s)
+ }
+ }
+ }
+}
+
+impl ham::Matcher<Output> for Execs {
+ fn matches(&self, output: Output) -> ham::MatchResult {
+ self.match_output(&output)
+ }
+}
+
+pub fn execs() -> Execs {
+ Execs {
+ expect_stdout: None,
+ expect_stderr: None,
+ expect_stdin: None,
+ expect_exit_code: None,
+ expect_stdout_contains: Vec::new(),
+ expect_stderr_contains: Vec::new(),
+ expect_json: None,
+ }
+}
+
+#[derive(Clone)]
+pub struct ShellWrites {
+ expected: String
+}
+
+impl fmt::Display for ShellWrites {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "`{}` written to the shell", self.expected)
+ }
+}
+
+impl<'a> ham::Matcher<&'a [u8]> for ShellWrites {
+ fn matches(&self, actual: &[u8])
+ -> ham::MatchResult
+ {
+ let actual = String::from_utf8_lossy(actual);
+ let actual = actual.to_string();
+ ham::expect(actual == self.expected, actual)
+ }
+}
+
+pub fn shell_writes<T: fmt::Display>(string: T) -> ShellWrites {
+ ShellWrites { expected: string.to_string() }
+}
+
+pub trait Tap {
+ fn tap<F: FnOnce(&mut Self)>(mut self, callback: F) -> Self;
+}
+
+impl<T> Tap for T {
+ fn tap<F: FnOnce(&mut Self)>(mut self, callback: F) -> T {
+ callback(&mut self);
+ self
+ }
+}
+
+pub fn basic_bin_manifest(name: &str) -> String {
+ format!(r#"
+ [package]
+
+ name = "{}"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [[bin]]
+
+ name = "{}"
+ "#, name, name)
+}
+
+pub fn basic_lib_manifest(name: &str) -> String {
+ format!(r#"
+ [package]
+
+ name = "{}"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib]
+
+ name = "{}"
+ "#, name, name)
+}
+
+pub fn path2url(p: PathBuf) -> Url {
+ Url::from_file_path(&*p).ok().unwrap()
+}
+
+fn substitute_macros(input: &str) -> String {
+ let macros = [
+ ("[RUNNING]", " Running"),
+ ("[COMPILING]", " Compiling"),
+ ("[ERROR]", "error:"),
+ ("[WARNING]", "warning:"),
+ ("[DOCUMENTING]", " Documenting"),
+ ("[FRESH]", " Fresh"),
+ ("[UPDATING]", " Updating"),
+ ("[ADDING]", " Adding"),
+ ("[REMOVING]", " Removing"),
+ ("[DOCTEST]", " Doc-tests"),
+ ("[PACKAGING]", " Packaging"),
+ ("[DOWNLOADING]", " Downloading"),
+ ("[UPLOADING]", " Uploading"),
+ ("[VERIFYING]", " Verifying"),
+ ("[ARCHIVING]", " Archiving"),
+ ("[INSTALLING]", " Installing"),
+ ("[REPLACING]", " Replacing")
+ ];
+ let mut result = input.to_owned();
+ for &(pat, subst) in macros.iter() {
+ result = result.replace(pat, subst)
+ }
+ return result;
+}
--- /dev/null
+use std::env;
+use std::cell::Cell;
+use std::fs;
+use std::io::{self, ErrorKind};
+use std::path::{Path, PathBuf};
+use std::sync::{Once, ONCE_INIT};
+use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
+
+use filetime::{self, FileTime};
+
+static CARGO_INTEGRATION_TEST_DIR : &'static str = "cit";
+static NEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;
+
+thread_local!(static TASK_ID: usize = NEXT_ID.fetch_add(1, Ordering::SeqCst));
+
+fn init() {
+ static GLOBAL_INIT: Once = ONCE_INIT;
+ thread_local!(static LOCAL_INIT: Cell<bool> = Cell::new(false));
+ GLOBAL_INIT.call_once(|| {
+ global_root().mkdir_p();
+ });
+ LOCAL_INIT.with(|i| {
+ if i.get() {
+ return
+ }
+ i.set(true);
+ root().rm_rf();
+ home().mkdir_p();
+ })
+}
+
+fn global_root() -> PathBuf {
+ let mut path = t!(env::current_exe());
+ path.pop(); // chop off exe name
+ path.pop(); // chop off 'debug'
+
+ // If `cargo test` is run manually then our path looks like
+ // `target/debug/foo`, in which case our `path` is already pointing at
+ // `target`. If, however, `cargo test --target $target` is used then the
+ // output is `target/$target/debug/foo`, so our path is pointing at
+ // `target/$target`. Here we conditionally pop the `$target` name.
+ if path.file_name().and_then(|s| s.to_str()) != Some("target") {
+ path.pop();
+ }
+
+ path.join(CARGO_INTEGRATION_TEST_DIR)
+}
+
+pub fn root() -> PathBuf {
+ init();
+ global_root().join(&TASK_ID.with(|my_id| format!("t{}", my_id)))
+}
+
+pub fn home() -> PathBuf {
+ root().join("home")
+}
+
+pub trait CargoPathExt {
+ fn rm_rf(&self);
+ fn mkdir_p(&self);
+ fn move_into_the_past(&self);
+}
+
+impl CargoPathExt for Path {
+ /* Technically there is a potential race condition, but we don't
+ * care all that much for our tests
+ */
+ fn rm_rf(&self) {
+ if !self.exists() {
+ return
+ }
+
+ for file in t!(fs::read_dir(self)) {
+ let file = t!(file).path();
+
+ if file.is_dir() {
+ file.rm_rf();
+ } else {
+ // On windows we can't remove a readonly file, and git will
+ // often clone files as readonly. As a result, we have some
+ // special logic to remove readonly files on windows.
+ do_op(&file, "remove file", |p| fs::remove_file(p));
+ }
+ }
+ do_op(self, "remove dir", |p| fs::remove_dir(p));
+ }
+
+ fn mkdir_p(&self) {
+ fs::create_dir_all(self).unwrap_or_else(|e| {
+ panic!("failed to mkdir_p {}: {}", self.display(), e)
+ })
+ }
+
+ fn move_into_the_past(&self) {
+ if self.is_file() {
+ time_travel(self);
+ } else {
+ recurse(self, &self.join("target"));
+ }
+
+ fn recurse(p: &Path, bad: &Path) {
+ if p.is_file() {
+ time_travel(p)
+ } else if !p.starts_with(bad) {
+ for f in t!(fs::read_dir(p)) {
+ let f = t!(f).path();
+ recurse(&f, bad);
+ }
+ }
+ }
+
+ fn time_travel(path: &Path) {
+ let stat = t!(path.metadata());
+
+ let mtime = FileTime::from_last_modification_time(&stat);
+ let newtime = mtime.seconds_relative_to_1970() - 3600;
+ let nanos = mtime.nanoseconds();
+ let newtime = FileTime::from_seconds_since_1970(newtime, nanos);
+
+ // Sadly change_file_times has a failure mode where a readonly file
+ // cannot have its times changed on windows.
+ do_op(path, "set file times",
+ |path| filetime::set_file_times(path, newtime, newtime));
+ }
+ }
+}
+
+fn do_op<F>(path: &Path, desc: &str, mut f: F)
+ where F: FnMut(&Path) -> io::Result<()>
+{
+ match f(path) {
+ Ok(()) => {}
+ Err(ref e) if cfg!(windows) &&
+ e.kind() == ErrorKind::PermissionDenied => {
+ let mut p = t!(path.metadata()).permissions();
+ p.set_readonly(false);
+ t!(fs::set_permissions(path, p));
+ f(path).unwrap_or_else(|e| {
+ panic!("failed to {} {}: {}", desc, path.display(), e);
+ })
+ }
+ Err(e) => {
+ panic!("failed to {} {}: {}", desc, path.display(), e);
+ }
+ }
+}
--- /dev/null
+use std::collections::HashMap;
+use std::fs::{self, File};
+use std::io::prelude::*;
+use std::path::{PathBuf, Path};
+
+use flate2::Compression::Default;
+use flate2::write::GzEncoder;
+use git2;
+use rustc_serialize::hex::ToHex;
+use rustc_serialize::json::ToJson;
+use tar::{Builder, Header};
+use url::Url;
+
+use support::paths;
+use support::git::repo;
+use cargo::util::Sha256;
+
+pub fn registry_path() -> PathBuf { paths::root().join("registry") }
+pub fn registry() -> Url { Url::from_file_path(&*registry_path()).ok().unwrap() }
+pub fn dl_path() -> PathBuf { paths::root().join("dl") }
+pub fn dl_url() -> Url { Url::from_file_path(&*dl_path()).ok().unwrap() }
+
+pub struct Package {
+ name: String,
+ vers: String,
+ deps: Vec<Dependency>,
+ files: Vec<(String, String)>,
+ yanked: bool,
+ features: HashMap<String, Vec<String>>,
+}
+
+struct Dependency {
+ name: String,
+ vers: String,
+ kind: String,
+ target: Option<String>,
+ features: Vec<String>,
+}
+
+fn init() {
+ let config = paths::home().join(".cargo/config");
+ t!(fs::create_dir_all(config.parent().unwrap()));
+ if fs::metadata(&config).is_ok() {
+ return
+ }
+ t!(t!(File::create(&config)).write_all(format!(r#"
+ [registry]
+ index = "{reg}"
+ token = "api-token"
+ "#, reg = registry()).as_bytes()));
+
+ // Init a new registry
+ repo(®istry_path())
+ .file("config.json", &format!(r#"
+ {{"dl":"{}","api":""}}
+ "#, dl_url()))
+ .build();
+}
+
+impl Package {
+ pub fn new(name: &str, vers: &str) -> Package {
+ init();
+ Package {
+ name: name.to_string(),
+ vers: vers.to_string(),
+ deps: Vec::new(),
+ files: Vec::new(),
+ yanked: false,
+ features: HashMap::new(),
+ }
+ }
+
+ pub fn file(&mut self, name: &str, contents: &str) -> &mut Package {
+ self.files.push((name.to_string(), contents.to_string()));
+ self
+ }
+
+ pub fn dep(&mut self, name: &str, vers: &str) -> &mut Package {
+ self.full_dep(name, vers, None, "normal", &[])
+ }
+
+ pub fn feature_dep(&mut self,
+ name: &str,
+ vers: &str,
+ features: &[&str]) -> &mut Package {
+ self.full_dep(name, vers, None, "normal", features)
+ }
+
+ pub fn target_dep(&mut self,
+ name: &str,
+ vers: &str,
+ target: &str) -> &mut Package {
+ self.full_dep(name, vers, Some(target), "normal", &[])
+ }
+
+ pub fn dev_dep(&mut self, name: &str, vers: &str) -> &mut Package {
+ self.full_dep(name, vers, None, "dev", &[])
+ }
+
+ fn full_dep(&mut self,
+ name: &str,
+ vers: &str,
+ target: Option<&str>,
+ kind: &str,
+ features: &[&str]) -> &mut Package {
+ self.deps.push(Dependency {
+ name: name.to_string(),
+ vers: vers.to_string(),
+ kind: kind.to_string(),
+ target: target.map(|s| s.to_string()),
+ features: features.iter().map(|s| s.to_string()).collect(),
+ });
+ self
+ }
+
+ pub fn yanked(&mut self, yanked: bool) -> &mut Package {
+ self.yanked = yanked;
+ self
+ }
+
+ pub fn publish(&self) {
+ self.make_archive();
+
+ // Figure out what we're going to write into the index
+ let deps = self.deps.iter().map(|dep| {
+ let mut map = HashMap::new();
+ map.insert("name".to_string(), dep.name.to_json());
+ map.insert("req".to_string(), dep.vers.to_json());
+ map.insert("features".to_string(), dep.features.to_json());
+ map.insert("default_features".to_string(), false.to_json());
+ map.insert("target".to_string(), dep.target.to_json());
+ map.insert("optional".to_string(), false.to_json());
+ map.insert("kind".to_string(), dep.kind.to_json());
+ map
+ }).collect::<Vec<_>>();
+ let cksum = {
+ let mut c = Vec::new();
+ t!(t!(File::open(&self.archive_dst())).read_to_end(&mut c));
+ cksum(&c)
+ };
+ let mut dep = HashMap::new();
+ dep.insert("name".to_string(), self.name.to_json());
+ dep.insert("vers".to_string(), self.vers.to_json());
+ dep.insert("deps".to_string(), deps.to_json());
+ dep.insert("cksum".to_string(), cksum.to_json());
+ dep.insert("features".to_string(), self.features.to_json());
+ dep.insert("yanked".to_string(), self.yanked.to_json());
+ let line = dep.to_json().to_string();
+
+ let file = match self.name.len() {
+ 1 => format!("1/{}", self.name),
+ 2 => format!("2/{}", self.name),
+ 3 => format!("3/{}/{}", &self.name[..1], self.name),
+ _ => format!("{}/{}/{}", &self.name[0..2], &self.name[2..4], self.name),
+ };
+
+ // Write file/line in the index
+ let dst = registry_path().join(&file);
+ let mut prev = String::new();
+ let _ = File::open(&dst).and_then(|mut f| f.read_to_string(&mut prev));
+ t!(fs::create_dir_all(dst.parent().unwrap()));
+ t!(t!(File::create(&dst))
+ .write_all((prev + &line[..] + "\n").as_bytes()));
+
+ // Add the new file to the index
+ let repo = t!(git2::Repository::open(®istry_path()));
+ let mut index = t!(repo.index());
+ t!(index.add_path(Path::new(&file)));
+ t!(index.write());
+ let id = t!(index.write_tree());
+
+ // Commit this change
+ let tree = t!(repo.find_tree(id));
+ let sig = t!(repo.signature());
+ let parent = t!(repo.refname_to_id("refs/heads/master"));
+ let parent = t!(repo.find_commit(parent));
+ t!(repo.commit(Some("HEAD"), &sig, &sig,
+ "Another commit", &tree,
+ &[&parent]));
+ }
+
+ fn make_archive(&self) {
+ let mut manifest = format!(r#"
+ [package]
+ name = "{}"
+ version = "{}"
+ authors = []
+ "#, self.name, self.vers);
+ for dep in self.deps.iter() {
+ let target = match dep.target {
+ None => String::new(),
+ Some(ref s) => format!("target.{}.", s),
+ };
+ let kind = match &dep.kind[..] {
+ "build" => "build-",
+ "dev" => "dev-",
+ _ => ""
+ };
+ manifest.push_str(&format!(r#"
+ [{}{}dependencies.{}]
+ version = "{}"
+ "#, target, kind, dep.name, dep.vers));
+ }
+
+ let dst = self.archive_dst();
+ t!(fs::create_dir_all(dst.parent().unwrap()));
+ let f = t!(File::create(&dst));
+ let mut a = Builder::new(GzEncoder::new(f, Default));
+ self.append(&mut a, "Cargo.toml", &manifest);
+ if self.files.is_empty() {
+ self.append(&mut a, "src/lib.rs", "");
+ } else {
+ for &(ref name, ref contents) in self.files.iter() {
+ self.append(&mut a, name, contents);
+ }
+ }
+ }
+
+ fn append<W: Write>(&self, ar: &mut Builder<W>, file: &str, contents: &str) {
+ let mut header = Header::new_ustar();
+ header.set_size(contents.len() as u64);
+ t!(header.set_path(format!("{}-{}/{}", self.name, self.vers, file)));
+ header.set_cksum();
+
+ t!(ar.append(&header, contents.as_bytes()));
+ }
+
+ pub fn archive_dst(&self) -> PathBuf {
+ dl_path().join(&self.name).join(&self.vers).join("download")
+ }
+}
+
+fn cksum(s: &[u8]) -> String {
+ let mut sha = Sha256::new();
+ sha.update(s);
+ sha.finish().to_hex()
+}
--- /dev/null
+extern crate cargo;
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::str::FromStr;
+use std::fmt;
+
+use cargo::util::{Cfg, CfgExpr};
+use cargotest::{is_nightly, rustc_host};
+use cargotest::support::registry::Package;
+use cargotest::support::{project, execs};
+use hamcrest::assert_that;
+
+macro_rules! c {
+ ($a:ident) => (
+ Cfg::Name(stringify!($a).to_string())
+ );
+ ($a:ident = $e:expr) => (
+ Cfg::KeyPair(stringify!($a).to_string(), $e.to_string())
+ );
+}
+
+macro_rules! e {
+ (any($($t:tt),*)) => (CfgExpr::Any(vec![$(e!($t)),*]));
+ (all($($t:tt),*)) => (CfgExpr::All(vec![$(e!($t)),*]));
+ (not($($t:tt)*)) => (CfgExpr::Not(Box::new(e!($($t)*))));
+ (($($t:tt)*)) => (e!($($t)*));
+ ($($t:tt)*) => (CfgExpr::Value(c!($($t)*)));
+}
+
+fn good<T>(s: &str, expected: T)
+ where T: FromStr + PartialEq + fmt::Debug,
+ T::Err: fmt::Display
+{
+ let c = match T::from_str(s) {
+ Ok(c) => c,
+ Err(e) => panic!("failed to parse `{}`: {}", s, e),
+ };
+ assert_eq!(c, expected);
+}
+
+fn bad<T>(s: &str, err: &str)
+ where T: FromStr + fmt::Display, T::Err: fmt::Display
+{
+ let e = match T::from_str(s) {
+ Ok(cfg) => panic!("expected `{}` to not parse but got {}", s, cfg),
+ Err(e) => e.to_string(),
+ };
+ assert!(e.contains(err), "when parsing `{}`,\n\"{}\" not contained \
+ inside: {}", s, err, e);
+}
+
+#[test]
+fn cfg_syntax() {
+ good("foo", c!(foo));
+ good("_bar", c!(_bar));
+ good(" foo", c!(foo));
+ good(" foo ", c!(foo));
+ good(" foo = \"bar\"", c!(foo = "bar"));
+ good("foo=\"\"", c!(foo = ""));
+ good(" foo=\"3\" ", c!(foo = "3"));
+ good("foo = \"3 e\"", c!(foo = "3 e"));
+}
+
+#[test]
+fn cfg_syntax_bad() {
+ bad::<Cfg>("", "found nothing");
+ bad::<Cfg>(" ", "found nothing");
+ bad::<Cfg>("\t", "unexpected character");
+ bad::<Cfg>("7", "unexpected character");
+ bad::<Cfg>("=", "expected identifier");
+ bad::<Cfg>(",", "expected identifier");
+ bad::<Cfg>("(", "expected identifier");
+ bad::<Cfg>("foo (", "malformed cfg value");
+ bad::<Cfg>("bar =", "expected a string");
+ bad::<Cfg>("bar = \"", "unterminated string");
+ bad::<Cfg>("foo, bar", "malformed cfg value");
+}
+
+#[test]
+fn cfg_expr() {
+ good("foo", e!(foo));
+ good("_bar", e!(_bar));
+ good(" foo", e!(foo));
+ good(" foo ", e!(foo));
+ good(" foo = \"bar\"", e!(foo = "bar"));
+ good("foo=\"\"", e!(foo = ""));
+ good(" foo=\"3\" ", e!(foo = "3"));
+ good("foo = \"3 e\"", e!(foo = "3 e"));
+
+ good("all()", e!(all()));
+ good("all(a)", e!(all(a)));
+ good("all(a, b)", e!(all(a, b)));
+ good("all(a, )", e!(all(a)));
+ good("not(a = \"b\")", e!(not(a = "b")));
+ good("not(all(a))", e!(not(all(a))));
+}
+
+#[test]
+fn cfg_expr_bad() {
+ bad::<CfgExpr>(" ", "found nothing");
+ bad::<CfgExpr>(" all", "expected `(`");
+ bad::<CfgExpr>("all(a", "expected `)`");
+ bad::<CfgExpr>("not", "expected `(`");
+ bad::<CfgExpr>("not(a", "expected `)`");
+ bad::<CfgExpr>("a = ", "expected a string");
+ bad::<CfgExpr>("all(not())", "expected identifier");
+ bad::<CfgExpr>("foo(a)", "consider using all() or any() explicitly");
+}
+
+#[test]
+fn cfg_matches() {
+ assert!(e!(foo).matches(&[c!(bar), c!(foo), c!(baz)]));
+ assert!(e!(any(foo)).matches(&[c!(bar), c!(foo), c!(baz)]));
+ assert!(e!(any(foo, bar)).matches(&[c!(bar)]));
+ assert!(e!(any(foo, bar)).matches(&[c!(foo)]));
+ assert!(e!(all(foo, bar)).matches(&[c!(foo), c!(bar)]));
+ assert!(e!(all(foo, bar)).matches(&[c!(foo), c!(bar)]));
+ assert!(e!(not(foo)).matches(&[c!(bar)]));
+ assert!(e!(not(foo)).matches(&[]));
+ assert!(e!(any((not(foo)), (all(foo, bar)))).matches(&[c!(bar)]));
+ assert!(e!(any((not(foo)), (all(foo, bar)))).matches(&[c!(foo), c!(bar)]));
+
+ assert!(!e!(foo).matches(&[]));
+ assert!(!e!(foo).matches(&[c!(bar)]));
+ assert!(!e!(foo).matches(&[c!(fo)]));
+ assert!(!e!(any(foo)).matches(&[]));
+ assert!(!e!(any(foo)).matches(&[c!(bar)]));
+ assert!(!e!(any(foo)).matches(&[c!(bar), c!(baz)]));
+ assert!(!e!(all(foo)).matches(&[c!(bar), c!(baz)]));
+ assert!(!e!(all(foo, bar)).matches(&[c!(bar)]));
+ assert!(!e!(all(foo, bar)).matches(&[c!(foo)]));
+ assert!(!e!(all(foo, bar)).matches(&[]));
+ assert!(!e!(not(bar)).matches(&[c!(bar)]));
+ assert!(!e!(not(bar)).matches(&[c!(baz), c!(bar)]));
+ assert!(!e!(any((not(foo)), (all(foo, bar)))).matches(&[c!(foo)]));
+}
+
+#[test]
+fn cfg_easy() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [target.'cfg(unix)'.dependencies]
+ b = { path = 'b' }
+ [target."cfg(windows)".dependencies]
+ b = { path = 'b' }
+ "#)
+ .file("src/lib.rs", "extern crate b;")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("b/src/lib.rs", "");
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn dont_include() {
+ if !is_nightly() { return }
+
+ let other_family = if cfg!(unix) {"windows"} else {"unix"};
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [target.'cfg({})'.dependencies]
+ b = {{ path = 'b' }}
+ "#, other_family))
+ .file("src/lib.rs", "")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("b/src/lib.rs", "");
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] a v0.0.1 ([..])
+"));
+}
+
+#[test]
+fn works_through_the_registry() {
+ if !is_nightly() { return }
+
+ Package::new("foo", "0.1.0").publish();
+ Package::new("bar", "0.1.0")
+ .target_dep("foo", "0.1.0", "'cfg(unix)'")
+ .target_dep("foo", "0.1.0", "'cfg(windows)'")
+ .publish();
+
+ let p = project("a")
+ .file("Cargo.toml", &r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "0.1.0"
+ "#)
+ .file("src/lib.rs", "extern crate bar;");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry [..]
+[DOWNLOADING] [..]
+[DOWNLOADING] [..]
+[COMPILING] foo v0.1.0 ([..])
+[COMPILING] bar v0.1.0 ([..])
+[COMPILING] a v0.0.1 ([..])
+"));
+}
+
+#[test]
+fn bad_target_spec() {
+ let p = project("a")
+ .file("Cargo.toml", &r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [target.'cfg(4)'.dependencies]
+ bar = "0.1.0"
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ failed to parse `4` as a cfg expression
+
+Caused by:
+ unexpected character in cfg `4`, [..]
+"));
+}
+
+#[test]
+fn bad_target_spec2() {
+ let p = project("a")
+ .file("Cargo.toml", &r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [target.'cfg(foo =)'.dependencies]
+ bar = "0.1.0"
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ failed to parse `foo =` as a cfg expression
+
+Caused by:
+ expected a string, found nothing
+"));
+}
+
+#[test]
+fn multiple_match_ok() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [target.'cfg(unix)'.dependencies]
+ b = {{ path = 'b' }}
+ [target.'cfg(target_family = "unix")'.dependencies]
+ b = {{ path = 'b' }}
+ [target."cfg(windows)".dependencies]
+ b = {{ path = 'b' }}
+ [target.'cfg(target_family = "windows")'.dependencies]
+ b = {{ path = 'b' }}
+ [target."cfg(any(windows, unix))".dependencies]
+ b = {{ path = 'b' }}
+
+ [target.{}.dependencies]
+ b = {{ path = 'b' }}
+ "#, rustc_host()))
+ .file("src/lib.rs", "extern crate b;")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("b/src/lib.rs", "");
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn any_ok() {
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [target."cfg(any(windows, unix))".dependencies]
+ b = { path = 'b' }
+ "#)
+ .file("src/lib.rs", "extern crate b;")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("b/src/lib.rs", "");
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+}
--- /dev/null
+extern crate hamcrest;
+extern crate cargotest;
+
+use std::env;
+
+use cargotest::support::{git, project, execs, main_file, basic_bin_manifest};
+use cargotest::support::registry::Package;
+use hamcrest::{assert_that, existing_dir, existing_file, is_not};
+
+#[test]
+fn cargo_clean_simple() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+ assert_that(&p.build_dir(), existing_dir());
+
+ assert_that(p.cargo("clean"),
+ execs().with_status(0));
+ assert_that(&p.build_dir(), is_not(existing_dir()));
+}
+
+#[test]
+fn different_dir() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
+ .file("src/bar/a.rs", "");
+
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+ assert_that(&p.build_dir(), existing_dir());
+
+ assert_that(p.cargo("clean").cwd(&p.root().join("src")),
+ execs().with_status(0).with_stdout(""));
+ assert_that(&p.build_dir(), is_not(existing_dir()));
+}
+
+#[test]
+fn clean_multiple_packages() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.d1]
+ path = "d1"
+ [dependencies.d2]
+ path = "d2"
+
+ [[bin]]
+ name = "foo"
+ "#)
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
+ .file("d1/Cargo.toml", r#"
+ [package]
+ name = "d1"
+ version = "0.0.1"
+ authors = []
+
+ [[bin]]
+ name = "d1"
+ "#)
+ .file("d1/src/main.rs", "fn main() { println!(\"d1\"); }")
+ .file("d2/Cargo.toml", r#"
+ [package]
+ name = "d2"
+ version = "0.0.1"
+ authors = []
+
+ [[bin]]
+ name = "d2"
+ "#)
+ .file("d2/src/main.rs", "fn main() { println!(\"d2\"); }");
+ p.build();
+
+ assert_that(p.cargo_process("build").arg("-p").arg("d1").arg("-p").arg("d2")
+ .arg("-p").arg("foo"),
+ execs().with_status(0));
+
+ let d1_path = &p.build_dir().join("debug").join("deps")
+ .join(format!("d1{}", env::consts::EXE_SUFFIX));
+ let d2_path = &p.build_dir().join("debug").join("deps")
+ .join(format!("d2{}", env::consts::EXE_SUFFIX));
+
+
+ assert_that(&p.bin("foo"), existing_file());
+ assert_that(d1_path, existing_file());
+ assert_that(d2_path, existing_file());
+
+ assert_that(p.cargo("clean").arg("-p").arg("d1").arg("-p").arg("d2")
+ .cwd(&p.root().join("src")),
+ execs().with_status(0).with_stdout(""));
+ assert_that(&p.bin("foo"), existing_file());
+ assert_that(d1_path, is_not(existing_file()));
+ assert_that(d2_path, is_not(existing_file()));
+}
+
+#[test]
+fn clean_release() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ a = { path = "a" }
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo_process("build").arg("--release"),
+ execs().with_status(0));
+
+ assert_that(p.cargo("clean").arg("-p").arg("foo"),
+ execs().with_status(0));
+ assert_that(p.cargo("build").arg("--release"),
+ execs().with_status(0).with_stdout(""));
+
+ assert_that(p.cargo("clean").arg("-p").arg("foo").arg("--release"),
+ execs().with_status(0));
+ assert_that(p.cargo("build").arg("--release"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+"));
+}
+
+#[test]
+fn build_script() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("build.rs", r#"
+ use std::path::PathBuf;
+ use std::env;
+
+ fn main() {
+ let out = PathBuf::from(env::var_os("OUT_DIR").unwrap());
+ if env::var("FIRST").is_ok() {
+ std::fs::File::create(out.join("out")).unwrap();
+ } else {
+ assert!(!std::fs::metadata(out.join("out")).is_ok());
+ }
+ }
+ "#)
+ .file("a/src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo_process("build").env("FIRST", "1"),
+ execs().with_status(0));
+ assert_that(p.cargo("clean").arg("-p").arg("foo"),
+ execs().with_status(0));
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc build.rs [..]`
+[RUNNING] `[..]build-script-build[..]`
+[RUNNING] `rustc src[..]main.rs [..]`
+"));
+}
+
+#[test]
+fn clean_git() {
+ let git = git::new("dep", |project| {
+ project.file("Cargo.toml", r#"
+ [project]
+ name = "dep"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ }).unwrap();
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ dep = {{ git = '{}' }}
+ "#, git.url()))
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0));
+ assert_that(p.cargo("clean").arg("-p").arg("dep"),
+ execs().with_status(0).with_stdout(""));
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn registry() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "0.1"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("bar", "0.1.0").publish();
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0));
+ assert_that(p.cargo("clean").arg("-p").arg("bar"),
+ execs().with_status(0).with_stdout(""));
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+}
--- /dev/null
+extern crate cargo;
+extern crate cargotest;
+extern crate git2;
+extern crate hamcrest;
+
+use std::{env, str};
+use std::fs::{self, File};
+use std::io::Write;
+use std::net::TcpListener;
+use std::process::Stdio;
+use std::thread;
+
+use cargotest::install::{has_installed_exe, cargo_home};
+use cargotest::support::git;
+use cargotest::support::registry::Package;
+use cargotest::support::{execs, project};
+use hamcrest::{assert_that, existing_file};
+
+fn pkg(name: &str, vers: &str) {
+ Package::new(name, vers)
+ .file("src/main.rs", "fn main() {{}}")
+ .publish();
+}
+
+#[test]
+fn multiple_installs() {
+ let p = project("foo")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+ "#)
+ .file("a/src/main.rs", "fn main() {}")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ authors = []
+ version = "0.0.0"
+ "#)
+ .file("b/src/main.rs", "fn main() {}");
+ p.build();
+
+ let mut a = p.cargo("install").cwd(p.root().join("a")).build_command();
+ let mut b = p.cargo("install").cwd(p.root().join("b")).build_command();
+
+ a.stdout(Stdio::piped()).stderr(Stdio::piped());
+ b.stdout(Stdio::piped()).stderr(Stdio::piped());
+
+ let a = a.spawn().unwrap();
+ let b = b.spawn().unwrap();
+ let a = thread::spawn(move || a.wait_with_output().unwrap());
+ let b = b.wait_with_output().unwrap();
+ let a = a.join().unwrap();
+
+ assert_that(a, execs().with_status(0));
+ assert_that(b, execs().with_status(0));
+
+ assert_that(cargo_home(), has_installed_exe("foo"));
+ assert_that(cargo_home(), has_installed_exe("bar"));
+}
+
+#[test]
+fn concurrent_installs() {
+ const LOCKED_BUILD: &'static str = "waiting for file lock on build directory";
+
+ pkg("foo", "0.0.1");
+ pkg("bar", "0.0.1");
+
+ let mut a = cargotest::cargo_process().arg("install").arg("foo").build_command();
+ let mut b = cargotest::cargo_process().arg("install").arg("bar").build_command();
+
+ a.stdout(Stdio::piped()).stderr(Stdio::piped());
+ b.stdout(Stdio::piped()).stderr(Stdio::piped());
+
+ let a = a.spawn().unwrap();
+ let b = b.spawn().unwrap();
+ let a = thread::spawn(move || a.wait_with_output().unwrap());
+ let b = b.wait_with_output().unwrap();
+ let a = a.join().unwrap();
+
+ assert!(!str::from_utf8(&a.stderr).unwrap().contains(LOCKED_BUILD));
+ assert!(!str::from_utf8(&b.stderr).unwrap().contains(LOCKED_BUILD));
+
+ assert_that(a, execs().with_status(0));
+ assert_that(b, execs().with_status(0));
+
+ assert_that(cargo_home(), has_installed_exe("foo"));
+ assert_that(cargo_home(), has_installed_exe("bar"));
+}
+
+#[test]
+fn one_install_should_be_bad() {
+ let p = project("foo")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+ "#)
+ .file("a/src/main.rs", "fn main() {}")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+ "#)
+ .file("b/src/main.rs", "fn main() {}");
+ p.build();
+
+ let mut a = p.cargo("install").cwd(p.root().join("a")).build_command();
+ let mut b = p.cargo("install").cwd(p.root().join("b")).build_command();
+
+ a.stdout(Stdio::piped()).stderr(Stdio::piped());
+ b.stdout(Stdio::piped()).stderr(Stdio::piped());
+
+ let a = a.spawn().unwrap();
+ let b = b.spawn().unwrap();
+ let a = thread::spawn(move || a.wait_with_output().unwrap());
+ let b = b.wait_with_output().unwrap();
+ let a = a.join().unwrap();
+
+ let (bad, good) = if a.status.code() == Some(101) {(a, b)} else {(b, a)};
+ assert_that(bad, execs().with_status(101).with_stderr_contains("\
+[ERROR] binary `foo[..]` already exists in destination as part of `[..]`
+"));
+ assert_that(good, execs().with_status(0).with_stderr_contains("\
+warning: be sure to add `[..]` to your PATH [..]
+"));
+
+ assert_that(cargo_home(), has_installed_exe("foo"));
+}
+
+#[test]
+fn multiple_registry_fetches() {
+ let mut pkg = Package::new("bar", "1.0.2");
+ for i in 0..10 {
+ let name = format!("foo{}", i);
+ Package::new(&name, "1.0.0").publish();
+ pkg.dep(&name, "*");
+ }
+ pkg.publish();
+
+ let p = project("foo")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+
+ [dependencies]
+ bar = "*"
+ "#)
+ .file("a/src/main.rs", "fn main() {}")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ authors = []
+ version = "0.0.0"
+
+ [dependencies]
+ bar = "*"
+ "#)
+ .file("b/src/main.rs", "fn main() {}");
+ p.build();
+
+ let mut a = p.cargo("build").cwd(p.root().join("a")).build_command();
+ let mut b = p.cargo("build").cwd(p.root().join("b")).build_command();
+
+ a.stdout(Stdio::piped()).stderr(Stdio::piped());
+ b.stdout(Stdio::piped()).stderr(Stdio::piped());
+
+ let a = a.spawn().unwrap();
+ let b = b.spawn().unwrap();
+ let a = thread::spawn(move || a.wait_with_output().unwrap());
+ let b = b.wait_with_output().unwrap();
+ let a = a.join().unwrap();
+
+ assert_that(a, execs().with_status(0));
+ assert_that(b, execs().with_status(0));
+
+ let suffix = env::consts::EXE_SUFFIX;
+ assert_that(&p.root().join("a/target/debug").join(format!("foo{}", suffix)),
+ existing_file());
+ assert_that(&p.root().join("b/target/debug").join(format!("bar{}", suffix)),
+ existing_file());
+}
+
+#[test]
+fn git_same_repo_different_tags() {
+ let a = git::new("dep", |project| {
+ project.file("Cargo.toml", r#"
+ [project]
+ name = "dep"
+ version = "0.5.0"
+ authors = []
+ "#).file("src/lib.rs", "pub fn tag1() {}")
+ }).unwrap();
+
+ let repo = git2::Repository::open(&a.root()).unwrap();
+ git::tag(&repo, "tag1");
+
+ File::create(a.root().join("src/lib.rs")).unwrap()
+ .write_all(b"pub fn tag2() {}").unwrap();
+ git::add(&repo);
+ git::commit(&repo);
+ git::tag(&repo, "tag2");
+
+ let p = project("foo")
+ .file("a/Cargo.toml", &format!(r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+
+ [dependencies]
+ dep = {{ git = '{}', tag = 'tag1' }}
+ "#, a.url()))
+ .file("a/src/main.rs", "extern crate dep; fn main() { dep::tag1(); }")
+ .file("b/Cargo.toml", &format!(r#"
+ [package]
+ name = "bar"
+ authors = []
+ version = "0.0.0"
+
+ [dependencies]
+ dep = {{ git = '{}', tag = 'tag2' }}
+ "#, a.url()))
+ .file("b/src/main.rs", "extern crate dep; fn main() { dep::tag2(); }");
+ p.build();
+
+ let mut a = p.cargo("build").arg("-v").cwd(p.root().join("a")).build_command();
+ let mut b = p.cargo("build").arg("-v").cwd(p.root().join("b")).build_command();
+
+ a.stdout(Stdio::piped()).stderr(Stdio::piped());
+ b.stdout(Stdio::piped()).stderr(Stdio::piped());
+
+ let a = a.spawn().unwrap();
+ let b = b.spawn().unwrap();
+ let a = thread::spawn(move || a.wait_with_output().unwrap());
+ let b = b.wait_with_output().unwrap();
+ let a = a.join().unwrap();
+
+ assert_that(a, execs().with_status(0));
+ assert_that(b, execs().with_status(0));
+}
+
+#[test]
+fn git_same_branch_different_revs() {
+ let a = git::new("dep", |project| {
+ project.file("Cargo.toml", r#"
+ [project]
+ name = "dep"
+ version = "0.5.0"
+ authors = []
+ "#).file("src/lib.rs", "pub fn f1() {}")
+ }).unwrap();
+
+ let p = project("foo")
+ .file("a/Cargo.toml", &format!(r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+
+ [dependencies]
+ dep = {{ git = '{}' }}
+ "#, a.url()))
+ .file("a/src/main.rs", "extern crate dep; fn main() { dep::f1(); }")
+ .file("b/Cargo.toml", &format!(r#"
+ [package]
+ name = "bar"
+ authors = []
+ version = "0.0.0"
+
+ [dependencies]
+ dep = {{ git = '{}' }}
+ "#, a.url()))
+ .file("b/src/main.rs", "extern crate dep; fn main() { dep::f2(); }");
+ p.build();
+
+ // Generate a Cargo.lock pointing at the current rev, then clear out the
+ // target directory
+ assert_that(p.cargo("build").cwd(p.root().join("a")),
+ execs().with_status(0));
+ fs::remove_dir_all(p.root().join("a/target")).unwrap();
+
+ // Make a new commit on the master branch
+ let repo = git2::Repository::open(&a.root()).unwrap();
+ File::create(a.root().join("src/lib.rs")).unwrap()
+ .write_all(b"pub fn f2() {}").unwrap();
+ git::add(&repo);
+ git::commit(&repo);
+
+ // Now run both builds in parallel. The build of `b` should pick up the
+ // newest commit while the build of `a` should use the locked old commit.
+ let mut a = p.cargo("build").cwd(p.root().join("a")).build_command();
+ let mut b = p.cargo("build").cwd(p.root().join("b")).build_command();
+
+ a.stdout(Stdio::piped()).stderr(Stdio::piped());
+ b.stdout(Stdio::piped()).stderr(Stdio::piped());
+
+ let a = a.spawn().unwrap();
+ let b = b.spawn().unwrap();
+ let a = thread::spawn(move || a.wait_with_output().unwrap());
+ let b = b.wait_with_output().unwrap();
+ let a = a.join().unwrap();
+
+ assert_that(a, execs().with_status(0));
+ assert_that(b, execs().with_status(0));
+}
+
+#[test]
+fn same_project() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("src/lib.rs", "");
+ p.build();
+
+ let mut a = p.cargo("build").build_command();
+ let mut b = p.cargo("build").build_command();
+
+ a.stdout(Stdio::piped()).stderr(Stdio::piped());
+ b.stdout(Stdio::piped()).stderr(Stdio::piped());
+
+ let a = a.spawn().unwrap();
+ let b = b.spawn().unwrap();
+ let a = thread::spawn(move || a.wait_with_output().unwrap());
+ let b = b.wait_with_output().unwrap();
+ let a = a.join().unwrap();
+
+ assert_that(a, execs().with_status(0));
+ assert_that(b, execs().with_status(0));
+}
+
+// Make sure that if Cargo dies while holding a lock that it's released and the
+// next Cargo to come in will take over cleanly.
+#[test]
+fn killing_cargo_releases_the_lock() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+ build = "build.rs"
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("build.rs", r#"
+ use std::net::TcpStream;
+
+ fn main() {
+ if std::env::var("A").is_ok() {
+ TcpStream::connect(&std::env::var("ADDR").unwrap()[..])
+ .unwrap();
+ std::thread::sleep(std::time::Duration::new(10, 0));
+ }
+ }
+ "#);
+ p.build();
+
+ // Our build script will connect to our local TCP socket to inform us that
+ // it's started and that's how we know that `a` will have the lock
+ // when we kill it.
+ let l = TcpListener::bind("127.0.0.1:0").unwrap();
+ let mut a = p.cargo("build").build_command();
+ let mut b = p.cargo("build").build_command();
+ a.stdout(Stdio::piped()).stderr(Stdio::piped());
+ b.stdout(Stdio::piped()).stderr(Stdio::piped());
+ a.env("ADDR", l.local_addr().unwrap().to_string()).env("A", "a");
+ b.env("ADDR", l.local_addr().unwrap().to_string()).env_remove("A");
+
+ // Spawn `a`, wait for it to get to the build script (at which point the
+ // lock is held), then kill it.
+ let mut a = a.spawn().unwrap();
+ l.accept().unwrap();
+ a.kill().unwrap();
+
+ // Spawn `b`, then just finish the output of a/b the same way the above
+ // tests does.
+ let b = b.spawn().unwrap();
+ let a = thread::spawn(move || a.wait_with_output().unwrap());
+ let b = b.wait_with_output().unwrap();
+ let a = a.join().unwrap();
+
+ // We killed `a`, so it shouldn't succeed, but `b` should have succeeded.
+ assert!(!a.status.success());
+ assert_that(b, execs().with_status(0));
+}
+
+#[test]
+fn debug_release_ok() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ assert_that(p.cargo("build"), execs().with_status(0));
+ fs::remove_dir_all(p.root().join("target")).unwrap();
+
+ let mut a = p.cargo("build").build_command();
+ let mut b = p.cargo("build").arg("--release").build_command();
+ a.stdout(Stdio::piped()).stderr(Stdio::piped());
+ b.stdout(Stdio::piped()).stderr(Stdio::piped());
+ let a = a.spawn().unwrap();
+ let b = b.spawn().unwrap();
+ let a = thread::spawn(move || a.wait_with_output().unwrap());
+ let b = b.wait_with_output().unwrap();
+ let a = a.join().unwrap();
+
+ assert_that(a, execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.0 [..]
+"));
+ assert_that(b, execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.0 [..]
+"));
+}
--- /dev/null
+extern crate hamcrest;
+extern crate cargotest;
+
+use cargotest::support::{project, execs};
+use hamcrest::assert_that;
+
+#[test]
+fn read_env_vars_for_config() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ use std::env;
+ fn main() {
+ assert_eq!(env::var("NUM_JOBS").unwrap(), "100");
+ }
+ "#);
+
+ assert_that(p.cargo_process("build").env("CARGO_BUILD_JOBS", "100"),
+ execs().with_status(0));
+}
--- /dev/null
+extern crate cargo;
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::env;
+
+use cargo::util::process;
+use cargotest::{is_nightly, rustc_host};
+use cargotest::support::{project, execs, basic_bin_manifest};
+use hamcrest::{assert_that, existing_file};
+
+fn disabled() -> bool {
+ // First, disable if ./configure requested so
+ match env::var("CFG_DISABLE_CROSS_TESTS") {
+ Ok(ref s) if *s == "1" => return true,
+ _ => {}
+ }
+
+ // Right now the windows bots cannot cross compile due to the mingw setup,
+ // so we disable ourselves on all but macos/linux setups where the rustc
+ // install script ensures we have both architectures
+ !(cfg!(target_os = "macos") ||
+ cfg!(target_os = "linux") ||
+ cfg!(target_env = "msvc"))
+}
+
+fn alternate() -> String {
+ let platform = match env::consts::OS {
+ "linux" => "unknown-linux-gnu",
+ "macos" => "apple-darwin",
+ "windows" => "pc-windows-msvc",
+ _ => unreachable!(),
+ };
+ let arch = match env::consts::ARCH {
+ "x86" => "x86_64",
+ "x86_64" => "i686",
+ _ => unreachable!(),
+ };
+ format!("{}-{}", arch, platform)
+}
+
+fn alternate_arch() -> &'static str {
+ match env::consts::ARCH {
+ "x86" => "x86_64",
+ "x86_64" => "x86",
+ _ => unreachable!(),
+ }
+}
+
+fn host() -> String {
+ let platform = match env::consts::OS {
+ "linux" => "unknown-linux-gnu",
+ "macos" => "apple-darwin",
+ "windows" => "pc-windows-msvc",
+ _ => unreachable!(),
+ };
+ let arch = match env::consts::ARCH {
+ "x86" => "i686",
+ "x86_64" => "x86_64",
+ _ => unreachable!(),
+ };
+ format!("{}-{}", arch, platform)
+}
+
+#[test]
+fn simple_cross() {
+ if disabled() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("build.rs", &format!(r#"
+ fn main() {{
+ assert_eq!(std::env::var("TARGET").unwrap(), "{}");
+ }}
+ "#, alternate()))
+ .file("src/main.rs", &format!(r#"
+ use std::env;
+ fn main() {{
+ assert_eq!(env::consts::ARCH, "{}");
+ }}
+ "#, alternate_arch()));
+
+ let target = alternate();
+ assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
+ execs().with_status(0));
+ assert_that(&p.target_bin(&target, "foo"), existing_file());
+
+ assert_that(process(&p.target_bin(&target, "foo")),
+ execs().with_status(0));
+}
+
+#[test]
+fn simple_cross_config() {
+ if disabled() { return }
+
+ let p = project("foo")
+ .file(".cargo/config", &format!(r#"
+ [build]
+ target = "{}"
+ "#, alternate()))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("build.rs", &format!(r#"
+ fn main() {{
+ assert_eq!(std::env::var("TARGET").unwrap(), "{}");
+ }}
+ "#, alternate()))
+ .file("src/main.rs", &format!(r#"
+ use std::env;
+ fn main() {{
+ assert_eq!(env::consts::ARCH, "{}");
+ }}
+ "#, alternate_arch()));
+
+ let target = alternate();
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+ assert_that(&p.target_bin(&target, "foo"), existing_file());
+
+ assert_that(process(&p.target_bin(&target, "foo")),
+ execs().with_status(0));
+}
+
+#[test]
+fn simple_deps() {
+ if disabled() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/main.rs", r#"
+ extern crate bar;
+ fn main() { bar::bar(); }
+ "#);
+ let p2 = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn bar() {}");
+ p2.build();
+
+ let target = alternate();
+ assert_that(p.cargo_process("build").arg("--target").arg(&target),
+ execs().with_status(0));
+ assert_that(&p.target_bin(&target, "foo"), existing_file());
+
+ assert_that(process(&p.target_bin(&target, "foo")),
+ execs().with_status(0));
+}
+
+#[test]
+fn plugin_deps() {
+ if disabled() { return }
+ if !is_nightly() { return }
+
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "../bar"
+
+ [dependencies.baz]
+ path = "../baz"
+ "#)
+ .file("src/main.rs", r#"
+ #![feature(plugin)]
+ #![plugin(bar)]
+ extern crate baz;
+ fn main() {
+ assert_eq!(bar!(), baz::baz());
+ }
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "bar"
+ plugin = true
+ "#)
+ .file("src/lib.rs", r#"
+ #![feature(plugin_registrar, quote, rustc_private)]
+
+ extern crate rustc_plugin;
+ extern crate syntax;
+
+ use rustc_plugin::Registry;
+ use syntax::ast::TokenTree;
+ use syntax::codemap::Span;
+ use syntax::ext::base::{ExtCtxt, MacEager, MacResult};
+
+ #[plugin_registrar]
+ pub fn foo(reg: &mut Registry) {
+ reg.register_macro("bar", expand_bar);
+ }
+
+ fn expand_bar(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
+ -> Box<MacResult + 'static> {
+ MacEager::expr(quote_expr!(cx, 1))
+ }
+ "#);
+ let baz = project("baz")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "baz"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn baz() -> i32 { 1 }");
+ bar.build();
+ baz.build();
+
+ let target = alternate();
+ assert_that(foo.cargo_process("build").arg("--target").arg(&target),
+ execs().with_status(0));
+ assert_that(&foo.target_bin(&target, "foo"), existing_file());
+
+ assert_that(process(&foo.target_bin(&target, "foo")),
+ execs().with_status(0));
+}
+
+#[test]
+fn plugin_to_the_max() {
+ if disabled() { return }
+ if !is_nightly() { return }
+
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "../bar"
+
+ [dependencies.baz]
+ path = "../baz"
+ "#)
+ .file("src/main.rs", r#"
+ #![feature(plugin)]
+ #![plugin(bar)]
+ extern crate baz;
+ fn main() {
+ assert_eq!(bar!(), baz::baz());
+ }
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "bar"
+ plugin = true
+
+ [dependencies.baz]
+ path = "../baz"
+ "#)
+ .file("src/lib.rs", r#"
+ #![feature(plugin_registrar, quote, rustc_private)]
+
+ extern crate rustc_plugin;
+ extern crate syntax;
+ extern crate baz;
+
+ use rustc_plugin::Registry;
+ use syntax::ast::TokenTree;
+ use syntax::codemap::Span;
+ use syntax::ext::base::{ExtCtxt, MacEager, MacResult};
+
+ #[plugin_registrar]
+ pub fn foo(reg: &mut Registry) {
+ reg.register_macro("bar", expand_bar);
+ }
+
+ fn expand_bar(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
+ -> Box<MacResult + 'static> {
+ MacEager::expr(quote_expr!(cx, baz::baz()))
+ }
+ "#);
+ let baz = project("baz")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "baz"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn baz() -> i32 { 1 }");
+ bar.build();
+ baz.build();
+
+ let target = alternate();
+ assert_that(foo.cargo_process("build").arg("--target").arg(&target).arg("-v"),
+ execs().with_status(0));
+ println!("second");
+ assert_that(foo.cargo("build").arg("-v")
+ .arg("--target").arg(&target),
+ execs().with_status(0));
+ assert_that(&foo.target_bin(&target, "foo"), existing_file());
+
+ assert_that(process(&foo.target_bin(&target, "foo")),
+ execs().with_status(0));
+}
+
+#[test]
+fn linker_and_ar() {
+ if disabled() { return }
+
+ let target = alternate();
+ let p = project("foo")
+ .file(".cargo/config", &format!(r#"
+ [target.{}]
+ ar = "my-ar-tool"
+ linker = "my-linker-tool"
+ "#, target))
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &format!(r#"
+ use std::env;
+ fn main() {{
+ assert_eq!(env::consts::ARCH, "{}");
+ }}
+ "#, alternate_arch()));
+
+ assert_that(p.cargo_process("build").arg("--target").arg(&target)
+ .arg("-v"),
+ execs().with_status(101)
+ .with_stderr_contains(&format!("\
+[COMPILING] foo v0.5.0 ({url})
+[RUNNING] `rustc src[..]foo.rs --crate-name foo --crate-type bin -g \
+ --out-dir {dir}[..]target[..]{target}[..]debug \
+ --emit=dep-info,link \
+ --target {target} \
+ -C ar=my-ar-tool -C linker=my-linker-tool \
+ -L dependency={dir}[..]target[..]{target}[..]debug \
+ -L dependency={dir}[..]target[..]{target}[..]debug[..]deps`
+",
+ dir = p.root().display(),
+ url = p.url(),
+ target = target,
+ )));
+}
+
+#[test]
+fn plugin_with_extra_dylib_dep() {
+ if disabled() { return }
+ if !is_nightly() { return }
+
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/main.rs", r#"
+ #![feature(plugin)]
+ #![plugin(bar)]
+
+ fn main() {}
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "bar"
+ plugin = true
+
+ [dependencies.baz]
+ path = "../baz"
+ "#)
+ .file("src/lib.rs", r#"
+ #![feature(plugin_registrar, rustc_private)]
+
+ extern crate rustc_plugin;
+ extern crate baz;
+
+ use rustc_plugin::Registry;
+
+ #[plugin_registrar]
+ pub fn foo(reg: &mut Registry) {
+ println!("{}", baz::baz());
+ }
+ "#);
+ let baz = project("baz")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "baz"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "baz"
+ crate_type = ["dylib"]
+ "#)
+ .file("src/lib.rs", "pub fn baz() -> i32 { 1 }");
+ bar.build();
+ baz.build();
+
+ let target = alternate();
+ assert_that(foo.cargo_process("build").arg("--target").arg(&target),
+ execs().with_status(0));
+}
+
+#[test]
+fn cross_tests() {
+ if disabled() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+
+ [[bin]]
+ name = "bar"
+ "#)
+ .file("src/main.rs", &format!(r#"
+ extern crate foo;
+ use std::env;
+ fn main() {{
+ assert_eq!(env::consts::ARCH, "{}");
+ }}
+ #[test] fn test() {{ main() }}
+ "#, alternate_arch()))
+ .file("src/lib.rs", &format!(r#"
+ use std::env;
+ pub fn foo() {{ assert_eq!(env::consts::ARCH, "{}"); }}
+ #[test] fn test_foo() {{ foo() }}
+ "#, alternate_arch()));
+
+ let target = alternate();
+ assert_that(p.cargo_process("test").arg("--target").arg(&target),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.0 ({foo})
+[RUNNING] target[..]{triple}[..]bar-[..]
+[RUNNING] target[..]{triple}[..]foo-[..]", foo = p.url(), triple = target))
+ .with_stdout("
+running 1 test
+test test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test test_foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn no_cross_doctests() {
+ if disabled() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ authors = []
+ version = "0.0.0"
+ "#)
+ .file("src/lib.rs", r#"
+ //! ```
+ //! extern crate foo;
+ //! assert!(true);
+ //! ```
+ "#);
+
+ let host_output = format!("\
+[COMPILING] foo v0.0.0 ({foo})
+[RUNNING] target[..]foo-[..]
+[DOCTEST] foo
+", foo = p.url());
+
+ println!("a");
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0)
+ .with_stderr(&host_output));
+
+ println!("b");
+ let target = host();
+ assert_that(p.cargo_process("test").arg("--target").arg(&target),
+ execs().with_status(0)
+ .with_stderr(&host_output));
+
+ println!("c");
+ let target = alternate();
+ assert_that(p.cargo_process("test").arg("--target").arg(&target),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.0 ({foo})
+[RUNNING] target[..]{triple}[..]foo-[..]
+", foo = p.url(), triple = target)));
+}
+
+#[test]
+fn simple_cargo_run() {
+ if disabled() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("src/main.rs", &format!(r#"
+ use std::env;
+ fn main() {{
+ assert_eq!(env::consts::ARCH, "{}");
+ }}
+ "#, alternate_arch()));
+
+ let target = alternate();
+ assert_that(p.cargo_process("run").arg("--target").arg(&target),
+ execs().with_status(0));
+}
+
+#[test]
+fn cross_with_a_build_script() {
+ if disabled() { return }
+
+ let target = alternate();
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ build = 'build.rs'
+ "#)
+ .file("build.rs", &format!(r#"
+ use std::env;
+ use std::path::PathBuf;
+ fn main() {{
+ assert_eq!(env::var("TARGET").unwrap(), "{0}");
+ let mut path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
+ assert_eq!(path.file_name().unwrap().to_str().unwrap(), "out");
+ path.pop();
+ assert!(path.file_name().unwrap().to_str().unwrap()
+ .starts_with("foo-"));
+ path.pop();
+ assert_eq!(path.file_name().unwrap().to_str().unwrap(), "build");
+ path.pop();
+ assert_eq!(path.file_name().unwrap().to_str().unwrap(), "debug");
+ path.pop();
+ assert_eq!(path.file_name().unwrap().to_str().unwrap(), "{0}");
+ path.pop();
+ assert_eq!(path.file_name().unwrap().to_str().unwrap(), "target");
+ }}
+ "#, target))
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.0 (file://[..])
+[RUNNING] `rustc build.rs [..] --out-dir {dir}[..]target[..]build[..]foo-[..]`
+[RUNNING] `{dir}[..]target[..]build[..]foo-[..]build-script-build`
+[RUNNING] `rustc src[..]main.rs [..] --target {target} [..]`
+", target = target,
+ dir = p.root().display())));
+}
+
+#[test]
+fn build_script_needed_for_host_and_target() {
+ if disabled() { return }
+
+ let target = alternate();
+ let host = rustc_host();
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ build = 'build.rs'
+
+ [dependencies.d1]
+ path = "d1"
+ [build-dependencies.d2]
+ path = "d2"
+ "#)
+
+ .file("build.rs", r#"
+ extern crate d2;
+ fn main() { d2::d2(); }
+ "#)
+ .file("src/main.rs", "
+ extern crate d1;
+ fn main() { d1::d1(); }
+ ")
+ .file("d1/Cargo.toml", r#"
+ [package]
+ name = "d1"
+ version = "0.0.0"
+ authors = []
+ build = 'build.rs'
+ "#)
+ .file("d1/src/lib.rs", "
+ pub fn d1() {}
+ ")
+ .file("d1/build.rs", r#"
+ use std::env;
+ fn main() {
+ let target = env::var("TARGET").unwrap();
+ println!("cargo:rustc-flags=-L /path/to/{}", target);
+ }
+ "#)
+ .file("d2/Cargo.toml", r#"
+ [package]
+ name = "d2"
+ version = "0.0.0"
+ authors = []
+
+ [dependencies.d1]
+ path = "../d1"
+ "#)
+ .file("d2/src/lib.rs", "
+ extern crate d1;
+ pub fn d2() { d1::d1(); }
+ ");
+
+ assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
+ execs().with_status(0)
+ .with_stderr_contains(&format!("\
+[COMPILING] d1 v0.0.0 ({url}/d1)", url = p.url()))
+ .with_stderr_contains(&format!("\
+[RUNNING] `rustc d1[..]build.rs [..] --out-dir {dir}[..]target[..]build[..]d1-[..]`",
+ dir = p.root().display()))
+ .with_stderr_contains(&format!("\
+[RUNNING] `{dir}[..]target[..]build[..]d1-[..]build-script-build`",
+ dir = p.root().display()))
+ .with_stderr_contains("\
+[RUNNING] `rustc d1[..]src[..]lib.rs [..]`")
+ .with_stderr_contains(&format!("\
+[COMPILING] d2 v0.0.0 ({url}/d2)", url = p.url()))
+ .with_stderr_contains(&format!("\
+[RUNNING] `rustc d2[..]src[..]lib.rs [..] \
+ -L /path/to/{host}`", host = host))
+ .with_stderr_contains(&format!("\
+[COMPILING] foo v0.0.0 ({url})", url = p.url()))
+ .with_stderr_contains(&format!("\
+[RUNNING] `rustc build.rs [..] --out-dir {dir}[..]target[..]build[..]foo-[..] \
+ -L /path/to/{host}`", dir = p.root().display(), host = host))
+ .with_stderr_contains(&format!("\
+[RUNNING] `rustc src[..]main.rs [..] --target {target} [..] \
+ -L /path/to/{target}`", target = target)));
+}
+
+#[test]
+fn build_deps_for_the_right_arch() {
+ if disabled() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+
+ [dependencies.d2]
+ path = "d2"
+ "#)
+ .file("src/main.rs", "extern crate d2; fn main() {}")
+ .file("d1/Cargo.toml", r#"
+ [package]
+ name = "d1"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("d1/src/lib.rs", "
+ pub fn d1() {}
+ ")
+ .file("d2/Cargo.toml", r#"
+ [package]
+ name = "d2"
+ version = "0.0.0"
+ authors = []
+ build = "build.rs"
+
+ [build-dependencies.d1]
+ path = "../d1"
+ "#)
+ .file("d2/build.rs", "extern crate d1; fn main() {}")
+ .file("d2/src/lib.rs", "");
+
+ let target = alternate();
+ assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn build_script_only_host() {
+ if disabled() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ build = "build.rs"
+
+ [build-dependencies.d1]
+ path = "d1"
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("build.rs", "extern crate d1; fn main() {}")
+ .file("d1/Cargo.toml", r#"
+ [package]
+ name = "d1"
+ version = "0.0.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("d1/src/lib.rs", "
+ pub fn d1() {}
+ ")
+ .file("d1/build.rs", r#"
+ use std::env;
+
+ fn main() {
+ assert!(env::var("OUT_DIR").unwrap().replace("\\", "/")
+ .contains("target/debug/build/d1-"),
+ "bad: {:?}", env::var("OUT_DIR"));
+ }
+ "#);
+
+ let target = alternate();
+ assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn plugin_build_script_right_arch() {
+ if disabled() { return }
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+
+ [lib]
+ name = "foo"
+ plugin = true
+ "#)
+ .file("build.rs", "fn main() {}")
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v").arg("--target").arg(alternate()),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc build.rs [..]`
+[RUNNING] `[..]build-script-build[..]`
+[RUNNING] `rustc src[..]lib.rs [..]`
+"));
+}
+
+#[test]
+fn build_script_with_platform_specific_dependencies() {
+ if disabled() { return }
+
+ let target = alternate();
+ let host = rustc_host();
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+
+ [build-dependencies.d1]
+ path = "d1"
+ "#)
+ .file("build.rs", "extern crate d1; fn main() {}")
+ .file("src/lib.rs", "")
+ .file("d1/Cargo.toml", &format!(r#"
+ [package]
+ name = "d1"
+ version = "0.0.0"
+ authors = []
+
+ [target.{}.dependencies]
+ d2 = {{ path = "../d2" }}
+ "#, host))
+ .file("d1/src/lib.rs", "extern crate d2;")
+ .file("d2/Cargo.toml", r#"
+ [package]
+ name = "d2"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("d2/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v").arg("--target").arg(&target),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] d2 v0.0.0 ([..])
+[RUNNING] `rustc d2[..]src[..]lib.rs [..]`
+[COMPILING] d1 v0.0.0 ([..])
+[RUNNING] `rustc d1[..]src[..]lib.rs [..]`
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc build.rs [..]`
+[RUNNING] `{dir}[..]target[..]build[..]foo-[..]build-script-build`
+[RUNNING] `rustc src[..]lib.rs [..] --target {target} [..]`
+", dir = p.root().display(), target = target)));
+}
+
+#[test]
+fn platform_specific_dependencies_do_not_leak() {
+ if disabled() { return }
+
+ let target = alternate();
+ let host = rustc_host();
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+
+ [dependencies.d1]
+ path = "d1"
+
+ [build-dependencies.d1]
+ path = "d1"
+ "#)
+ .file("build.rs", "extern crate d1; fn main() {}")
+ .file("src/lib.rs", "")
+ .file("d1/Cargo.toml", &format!(r#"
+ [package]
+ name = "d1"
+ version = "0.0.0"
+ authors = []
+
+ [target.{}.dependencies]
+ d2 = {{ path = "../d2" }}
+ "#, host))
+ .file("d1/src/lib.rs", "extern crate d2;")
+ .file("d2/Cargo.toml", r#"
+ [package]
+ name = "d2"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("d2/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v").arg("--target").arg(&target),
+ execs().with_status(101)
+ .with_stderr_contains("\
+[..] error: can't find crate for `d2`[..]"));
+}
+
+#[test]
+fn platform_specific_variables_reflected_in_build_scripts() {
+ if disabled() { return }
+
+ let target = alternate();
+ let host = rustc_host();
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+
+ [target.{host}.dependencies]
+ d1 = {{ path = "d1" }}
+
+ [target.{target}.dependencies]
+ d2 = {{ path = "d2" }}
+ "#, host = host, target = target))
+ .file("build.rs", &format!(r#"
+ use std::env;
+
+ fn main() {{
+ let platform = env::var("TARGET").unwrap();
+ let (expected, not_expected) = match &platform[..] {{
+ "{host}" => ("DEP_D1_VAL", "DEP_D2_VAL"),
+ "{target}" => ("DEP_D2_VAL", "DEP_D1_VAL"),
+ _ => panic!("unknown platform")
+ }};
+
+ env::var(expected).ok()
+ .expect(&format!("missing {{}}", expected));
+ env::var(not_expected).err()
+ .expect(&format!("found {{}}", not_expected));
+ }}
+ "#, host = host, target = target))
+ .file("src/lib.rs", "")
+ .file("d1/Cargo.toml", r#"
+ [package]
+ name = "d1"
+ version = "0.0.0"
+ authors = []
+ links = "d1"
+ build = "build.rs"
+ "#)
+ .file("d1/build.rs", r#"
+ fn main() { println!("cargo:val=1") }
+ "#)
+ .file("d1/src/lib.rs", "")
+ .file("d2/Cargo.toml", r#"
+ [package]
+ name = "d2"
+ version = "0.0.0"
+ authors = []
+ links = "d2"
+ build = "build.rs"
+ "#)
+ .file("d2/build.rs", r#"
+ fn main() { println!("cargo:val=1") }
+ "#)
+ .file("d2/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0));
+ assert_that(p.cargo_process("build").arg("-v").arg("--target").arg(&target),
+ execs().with_status(0));
+}
--- /dev/null
+extern crate cargotest;
+extern crate kernel32;
+extern crate libc;
+extern crate winapi;
+
+use std::net::TcpListener;
+use std::io::{self, Read};
+use std::process::{Stdio, Child};
+
+use cargotest::support::project;
+
+#[cfg(unix)]
+fn enabled() -> bool {
+ true
+}
+
+// On Windows suport for these tests is only enabled through the usage of job
+// objects. Support for nested job objects, however, was added in recent-ish
+// versions of Windows, so this test may not always be able to succeed.
+//
+// As a result, we try to add ourselves to a job object here
+// can succeed or not.
+#[cfg(windows)]
+fn enabled() -> bool {
+ use kernel32;
+ use winapi;
+ unsafe {
+ // If we're not currently in a job, then we can definitely run these
+ // tests.
+ let me = kernel32::GetCurrentProcess();
+ let mut ret = 0;
+ let r = kernel32::IsProcessInJob(me, 0 as *mut _, &mut ret);
+ assert!(r != 0);
+ if ret == winapi::FALSE {
+ return true
+ }
+
+ // If we are in a job, then we can run these tests if we can be added to
+ // a nested job (as we're going to create a nested job no matter what as
+ // part of these tests.
+ //
+ // If we can't be added to a nested job, then these tests will
+ // definitely fail, and there's not much we can do about that.
+ let job = kernel32::CreateJobObjectW(0 as *mut _, 0 as *const _);
+ assert!(!job.is_null());
+ let r = kernel32::AssignProcessToJobObject(job, me);
+ kernel32::CloseHandle(job);
+ r != 0
+ }
+}
+
+#[test]
+fn ctrl_c_kills_everyone() {
+ if !enabled() {
+ return
+ }
+
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
+ let addr = listener.local_addr().unwrap();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", &format!(r#"
+ use std::net::TcpStream;
+ use std::io::Read;
+
+ fn main() {{
+ let mut socket = TcpStream::connect("{}").unwrap();
+ let _ = socket.read(&mut [0; 10]);
+ panic!("that read should never return");
+ }}
+ "#, addr));
+ p.build();
+
+ let mut cargo = p.cargo("build").build_command();
+ cargo.stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .stderr(Stdio::piped())
+ .env("__CARGO_TEST_SETSID_PLEASE_DONT_USE_ELSEWHERE", "1");
+ let mut child = cargo.spawn().unwrap();
+
+ let mut sock = listener.accept().unwrap().0;
+ ctrl_c(&mut child);
+
+ assert!(!child.wait().unwrap().success());
+ match sock.read(&mut [0; 10]) {
+ Ok(n) => assert_eq!(n, 0),
+ Err(e) => assert_eq!(e.kind(), io::ErrorKind::ConnectionReset),
+ }
+}
+
+#[cfg(unix)]
+fn ctrl_c(child: &mut Child) {
+ use libc;
+
+ let r = unsafe { libc::kill(-(child.id() as i32), libc::SIGINT) };
+ if r < 0 {
+ panic!("failed to kill: {}", io::Error::last_os_error());
+ }
+}
+
+#[cfg(windows)]
+fn ctrl_c(child: &mut Child) {
+ child.kill().unwrap();
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::str;
+use std::fs;
+
+use cargotest::{is_nightly, rustc_host};
+use cargotest::support::{project, execs, path2url};
+use hamcrest::{assert_that, existing_file, existing_dir, is_not};
+
+#[test]
+fn simple() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("build.rs", "fn main() {}")
+ .file("src/lib.rs", r#"
+ pub fn foo() {}
+ "#);
+
+ assert_that(p.cargo_process("doc"),
+ execs().with_status(0).with_stderr(&format!("\
+[..] foo v0.0.1 ({dir})
+[..] foo v0.0.1 ({dir})
+",
+ dir = path2url(p.root()))));
+ assert_that(&p.root().join("target/doc"), existing_dir());
+ assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
+}
+
+#[test]
+fn doc_no_libs() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [[bin]]
+ name = "foo"
+ doc = false
+ "#)
+ .file("src/main.rs", r#"
+ bad code
+ "#);
+
+ assert_that(p.cargo_process("doc"),
+ execs().with_status(0));
+}
+
+#[test]
+fn doc_twice() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn foo() {}
+ "#);
+
+ assert_that(p.cargo_process("doc"),
+ execs().with_status(0).with_stderr(&format!("\
+[DOCUMENTING] foo v0.0.1 ({dir})
+",
+ dir = path2url(p.root()))));
+
+ assert_that(p.cargo("doc"),
+ execs().with_status(0).with_stdout(""))
+}
+
+#[test]
+fn doc_deps() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/lib.rs", r#"
+ extern crate bar;
+ pub fn foo() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", r#"
+ pub fn bar() {}
+ "#);
+
+ assert_that(p.cargo_process("doc"),
+ execs().with_status(0).with_stderr(&format!("\
+[..] bar v0.0.1 ({dir}/bar)
+[..] bar v0.0.1 ({dir}/bar)
+[DOCUMENTING] foo v0.0.1 ({dir})
+",
+ dir = path2url(p.root()))));
+
+ assert_that(&p.root().join("target/doc"), existing_dir());
+ assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
+ assert_that(&p.root().join("target/doc/bar/index.html"), existing_file());
+
+ assert_that(p.cargo("doc")
+ .env("RUST_LOG", "cargo::ops::cargo_rustc::fingerprint"),
+ execs().with_status(0).with_stdout(""));
+
+ assert_that(&p.root().join("target/doc"), existing_dir());
+ assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
+ assert_that(&p.root().join("target/doc/bar/index.html"), existing_file());
+}
+
+#[test]
+fn doc_no_deps() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/lib.rs", r#"
+ extern crate bar;
+ pub fn foo() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", r#"
+ pub fn bar() {}
+ "#);
+
+ assert_that(p.cargo_process("doc").arg("--no-deps"),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] bar v0.0.1 ({dir}/bar)
+[DOCUMENTING] foo v0.0.1 ({dir})
+",
+ dir = path2url(p.root()))));
+
+ assert_that(&p.root().join("target/doc"), existing_dir());
+ assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
+ assert_that(&p.root().join("target/doc/bar/index.html"), is_not(existing_file()));
+}
+
+#[test]
+fn doc_only_bin() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/main.rs", r#"
+ extern crate bar;
+ pub fn foo() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", r#"
+ pub fn bar() {}
+ "#);
+
+ assert_that(p.cargo_process("doc").arg("-v"),
+ execs().with_status(0));
+
+ assert_that(&p.root().join("target/doc"), existing_dir());
+ assert_that(&p.root().join("target/doc/bar/index.html"), existing_file());
+ assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
+}
+
+#[test]
+fn doc_lib_bin_same_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("src/lib.rs", "fn foo() {}");
+
+ assert_that(p.cargo_process("doc"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] cannot document a package where a library and a binary have the same name. \
+Consider renaming one or marking the target as `doc = false`
+"));
+}
+
+#[test]
+fn doc_dash_p() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.a]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "extern crate a;")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.b]
+ path = "../b"
+ "#)
+ .file("a/src/lib.rs", "extern crate b;")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("b/src/lib.rs", "");
+
+ assert_that(p.cargo_process("doc").arg("-p").arg("a"),
+ execs().with_status(0)
+ .with_stderr("\
+[..] b v0.0.1 (file://[..])
+[..] b v0.0.1 (file://[..])
+[DOCUMENTING] a v0.0.1 (file://[..])
+"));
+}
+
+#[test]
+fn doc_same_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/bin/main.rs", "fn main() {}")
+ .file("examples/main.rs", "fn main() {}")
+ .file("tests/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("doc"),
+ execs().with_status(0));
+}
+
+#[test]
+fn doc_target() {
+ const TARGET: &'static str = "arm-unknown-linux-gnueabihf";
+
+ if !is_nightly() { return }
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ #![feature(no_core)]
+ #![no_core]
+
+ extern {
+ pub static A: u32;
+ }
+ "#);
+
+ assert_that(p.cargo_process("doc").arg("--target").arg(TARGET).arg("--verbose"),
+ execs().with_status(0));
+ assert_that(&p.root().join(&format!("target/{}/doc", TARGET)), existing_dir());
+ assert_that(&p.root().join(&format!("target/{}/doc/foo/index.html", TARGET)), existing_file());
+}
+
+#[test]
+fn target_specific_not_documented() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [target.foo.dependencies]
+ a = { path = "a" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "not rust");
+
+ assert_that(p.cargo_process("doc"),
+ execs().with_status(0));
+}
+
+#[test]
+fn output_not_captured() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ a = { path = "a" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "
+ /// ```
+ /// ☃
+ /// ```
+ pub fn foo() {}
+ ");
+
+ let output = p.cargo_process("doc").exec_with_output().err().unwrap()
+ .output.unwrap();
+ let stderr = str::from_utf8(&output.stderr).unwrap();
+ assert!(stderr.contains("☃"), "no snowman\n{}", stderr);
+ assert!(stderr.contains("unknown start of token"), "no message\n{}", stderr);
+}
+
+#[test]
+fn target_specific_documented() {
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [target.foo.dependencies]
+ a = {{ path = "a" }}
+ [target.{}.dependencies]
+ a = {{ path = "a" }}
+ "#, rustc_host()))
+ .file("src/lib.rs", "
+ extern crate a;
+
+ /// test
+ pub fn foo() {}
+ ")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "
+ /// test
+ pub fn foo() {}
+ ");
+
+ assert_that(p.cargo_process("doc"),
+ execs().with_status(0));
+}
+
+#[test]
+fn no_document_build_deps() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [build-dependencies]
+ a = { path = "a" }
+ "#)
+ .file("src/lib.rs", "
+ pub fn foo() {}
+ ")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "
+ /// ```
+ /// ☃
+ /// ```
+ pub fn foo() {}
+ ");
+
+ assert_that(p.cargo_process("doc"),
+ execs().with_status(0));
+}
+
+#[test]
+fn doc_release() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("--release"),
+ execs().with_status(0));
+ assert_that(p.cargo("doc").arg("--release").arg("-v"),
+ execs().with_status(0)
+ .with_stderr("\
+[DOCUMENTING] foo v0.0.1 ([..])
+[RUNNING] `rustdoc src[..]lib.rs [..]`
+"));
+}
+
+#[test]
+fn doc_multiple_deps() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+
+ [dependencies.baz]
+ path = "baz"
+ "#)
+ .file("src/lib.rs", r#"
+ extern crate bar;
+ pub fn foo() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", r#"
+ pub fn bar() {}
+ "#)
+ .file("baz/Cargo.toml", r#"
+ [package]
+ name = "baz"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("baz/src/lib.rs", r#"
+ pub fn baz() {}
+ "#);
+
+ assert_that(p.cargo_process("doc")
+ .arg("-p").arg("bar")
+ .arg("-p").arg("baz")
+ .arg("-v"),
+ execs().with_status(0));
+
+ assert_that(&p.root().join("target/doc"), existing_dir());
+ assert_that(&p.root().join("target/doc/bar/index.html"), existing_file());
+ assert_that(&p.root().join("target/doc/baz/index.html"), existing_file());
+}
+
+#[test]
+fn features() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+
+ [features]
+ foo = ["bar/bar"]
+ "#)
+ .file("src/lib.rs", r#"
+ #[cfg(feature = "foo")]
+ pub fn foo() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ bar = []
+ "#)
+ .file("bar/build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-cfg=bar");
+ }
+ "#)
+ .file("bar/src/lib.rs", r#"
+ #[cfg(feature = "bar")]
+ pub fn bar() {}
+ "#);
+ assert_that(p.cargo_process("doc").arg("--features").arg("foo"),
+ execs().with_status(0));
+ assert_that(&p.root().join("target/doc"), existing_dir());
+ assert_that(&p.root().join("target/doc/foo/fn.foo.html"), existing_file());
+ assert_that(&p.root().join("target/doc/bar/fn.bar.html"), existing_file());
+}
+
+#[test]
+fn rerun_when_dir_removed() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ /// dox
+ pub fn foo() {}
+ "#);
+ assert_that(p.cargo_process("doc"),
+ execs().with_status(0));
+ assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
+
+ fs::remove_dir_all(p.root().join("target/doc/foo")).unwrap();
+
+ assert_that(p.cargo_process("doc"),
+ execs().with_status(0));
+ assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
+}
+
+#[test]
+fn document_only_lib() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ /// dox
+ pub fn foo() {}
+ "#)
+ .file("src/bin/bar.rs", r#"
+ /// ```
+ /// ☃
+ /// ```
+ pub fn foo() {}
+ fn main() { foo(); }
+ "#);
+ assert_that(p.cargo_process("doc").arg("--lib"),
+ execs().with_status(0));
+ assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
+}
--- /dev/null
+#[macro_use]
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::fs::File;
+use std::io::prelude::*;
+
+use cargotest::support::paths::CargoPathExt;
+use cargotest::support::{project, execs};
+use hamcrest::assert_that;
+
+#[test]
+fn invalid1() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ bar = ["baz"]
+ "#)
+ .file("src/main.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ Feature `bar` includes `baz` which is neither a dependency nor another feature
+"));
+}
+
+#[test]
+fn invalid2() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ bar = ["baz"]
+
+ [dependencies.bar]
+ path = "foo"
+ "#)
+ .file("src/main.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ Features and dependencies cannot have the same name: `bar`
+"));
+}
+
+#[test]
+fn invalid3() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ bar = ["baz"]
+
+ [dependencies.baz]
+ path = "foo"
+ "#)
+ .file("src/main.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ Feature `bar` depends on `baz` which is not an optional dependency.
+Consider adding `optional = true` to the dependency
+"));
+}
+
+#[test]
+fn invalid4() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ features = ["bar"]
+ "#)
+ .file("src/main.rs", "")
+ .file("bar/Cargo.toml", r#"
+ [project]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[ERROR] Package `bar v0.0.1 ([..])` does not have these features: `bar`
+"));
+
+ let p = p.file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#);
+
+ assert_that(p.cargo_process("build").arg("--features").arg("test"),
+ execs().with_status(101).with_stderr("\
+[ERROR] Package `foo v0.0.1 ([..])` does not have these features: `test`
+"));
+}
+
+#[test]
+fn invalid5() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dev-dependencies.bar]
+ path = "bar"
+ optional = true
+ "#)
+ .file("src/main.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ Dev-dependencies are not allowed to be optional: `bar`
+"));
+}
+
+#[test]
+fn invalid6() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ foo = ["bar/baz"]
+ "#)
+ .file("src/main.rs", "");
+
+ assert_that(p.cargo_process("build").arg("--features").arg("foo"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ Feature `foo` requires `bar` which is not an optional dependency
+"));
+}
+
+#[test]
+fn invalid7() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ foo = ["bar/baz"]
+ bar = []
+ "#)
+ .file("src/main.rs", "");
+
+ assert_that(p.cargo_process("build").arg("--features").arg("foo"),
+ execs().with_status(101).with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ Feature `foo` requires `bar` which is not an optional dependency
+"));
+}
+
+#[test]
+fn invalid8() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ features = ["foo/bar"]
+ "#)
+ .file("src/main.rs", "")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build").arg("--features").arg("foo"),
+ execs().with_status(101).with_stderr("\
+[ERROR] features in dependencies cannot enable features in other dependencies: `foo/bar`
+"));
+}
+
+#[test]
+fn no_feature_doesnt_build() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ optional = true
+ "#)
+ .file("src/main.rs", r#"
+ #[cfg(feature = "bar")]
+ extern crate bar;
+ #[cfg(feature = "bar")]
+ fn main() { bar::bar(); println!("bar") }
+ #[cfg(not(feature = "bar"))]
+ fn main() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "pub fn bar() {}");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({dir})
+", dir = p.url())));
+ assert_that(p.process(&p.bin("foo")),
+ execs().with_status(0).with_stdout(""));
+
+ assert_that(p.cargo("build").arg("--features").arg("bar"),
+ execs().with_status(0).with_stderr(format!("\
+[COMPILING] bar v0.0.1 ({dir}/bar)
+[COMPILING] foo v0.0.1 ({dir})
+", dir = p.url())));
+ assert_that(p.process(&p.bin("foo")),
+ execs().with_status(0).with_stdout("bar\n"));
+}
+
+#[test]
+fn default_feature_pulled_in() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["bar"]
+
+ [dependencies.bar]
+ path = "bar"
+ optional = true
+ "#)
+ .file("src/main.rs", r#"
+ #[cfg(feature = "bar")]
+ extern crate bar;
+ #[cfg(feature = "bar")]
+ fn main() { bar::bar(); println!("bar") }
+ #[cfg(not(feature = "bar"))]
+ fn main() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "pub fn bar() {}");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr(format!("\
+[COMPILING] bar v0.0.1 ({dir}/bar)
+[COMPILING] foo v0.0.1 ({dir})
+", dir = p.url())));
+ assert_that(p.process(&p.bin("foo")),
+ execs().with_status(0).with_stdout("bar\n"));
+
+ assert_that(p.cargo("build").arg("--no-default-features"),
+ execs().with_status(0).with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({dir})
+", dir = p.url())));
+ assert_that(p.process(&p.bin("foo")),
+ execs().with_status(0).with_stdout(""));
+}
+
+#[test]
+fn cyclic_feature() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["default"]
+ "#)
+ .file("src/main.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[ERROR] Cyclic feature dependency: feature `default` depends on itself
+"));
+}
+
+#[test]
+fn cyclic_feature2() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ foo = ["bar"]
+ bar = ["foo"]
+ "#)
+ .file("src/main.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[ERROR] Cyclic feature dependency: feature `[..]` depends on itself
+"));
+}
+
+#[test]
+fn groups_on_groups_on_groups() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["f1"]
+ f1 = ["f2", "bar"]
+ f2 = ["f3", "f4"]
+ f3 = ["f5", "f6", "baz"]
+ f4 = ["f5", "f7"]
+ f5 = ["f6"]
+ f6 = ["f7"]
+ f7 = ["bar"]
+
+ [dependencies.bar]
+ path = "bar"
+ optional = true
+
+ [dependencies.baz]
+ path = "baz"
+ optional = true
+ "#)
+ .file("src/main.rs", r#"
+ extern crate bar;
+ extern crate baz;
+ fn main() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "pub fn bar() {}")
+ .file("baz/Cargo.toml", r#"
+ [package]
+ name = "baz"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("baz/src/lib.rs", "pub fn baz() {}");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr(format!("\
+[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
+[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
+[COMPILING] foo v0.0.1 ({dir})
+", dir = p.url())));
+}
+
+#[test]
+fn many_cli_features() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ optional = true
+
+ [dependencies.baz]
+ path = "baz"
+ optional = true
+ "#)
+ .file("src/main.rs", r#"
+ extern crate bar;
+ extern crate baz;
+ fn main() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "pub fn bar() {}")
+ .file("baz/Cargo.toml", r#"
+ [package]
+ name = "baz"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("baz/src/lib.rs", "pub fn baz() {}");
+
+ assert_that(p.cargo_process("build").arg("--features").arg("bar baz"),
+ execs().with_status(0).with_stderr(format!("\
+[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
+[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
+[COMPILING] foo v0.0.1 ({dir})
+", dir = p.url())));
+}
+
+#[test]
+fn union_features() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.d1]
+ path = "d1"
+ features = ["f1"]
+ [dependencies.d2]
+ path = "d2"
+ features = ["f2"]
+ "#)
+ .file("src/main.rs", r#"
+ extern crate d1;
+ extern crate d2;
+ fn main() {
+ d2::f1();
+ d2::f2();
+ }
+ "#)
+ .file("d1/Cargo.toml", r#"
+ [package]
+ name = "d1"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ f1 = ["d2"]
+
+ [dependencies.d2]
+ path = "../d2"
+ features = ["f1"]
+ optional = true
+ "#)
+ .file("d1/src/lib.rs", "")
+ .file("d2/Cargo.toml", r#"
+ [package]
+ name = "d2"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ f1 = []
+ f2 = []
+ "#)
+ .file("d2/src/lib.rs", r#"
+ #[cfg(feature = "f1")] pub fn f1() {}
+ #[cfg(feature = "f2")] pub fn f2() {}
+ "#);
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr(format!("\
+[COMPILING] d2 v0.0.1 ({dir}/d2)
+[COMPILING] d1 v0.0.1 ({dir}/d1)
+[COMPILING] foo v0.0.1 ({dir})
+", dir = p.url())));
+}
+
+#[test]
+fn many_features_no_rebuilds() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies.a]
+ path = "a"
+ features = ["fall"]
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.1.0"
+ authors = []
+
+ [features]
+ ftest = []
+ ftest2 = []
+ fall = ["ftest", "ftest2"]
+ "#)
+ .file("a/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr(format!("\
+[COMPILING] a v0.1.0 ({dir}/a)
+[COMPILING] b v0.1.0 ({dir})
+", dir = p.url())));
+ p.root().move_into_the_past();
+
+ assert_that(p.cargo("build").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[FRESH] a v0.1.0 ([..]/a)
+[FRESH] b v0.1.0 ([..])
+"));
+}
+
+// Tests that all cmd lines work with `--features ""`
+#[test]
+fn empty_features() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("build").arg("--features").arg(""),
+ execs().with_status(0));
+}
+
+// Tests that all cmd lines work with `--features ""`
+#[test]
+fn transitive_features() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ foo = ["bar/baz"]
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/main.rs", "
+ extern crate bar;
+ fn main() { bar::baz(); }
+ ")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ baz = []
+ "#)
+ .file("bar/src/lib.rs", r#"
+ #[cfg(feature = "baz")]
+ pub fn baz() {}
+ "#);
+
+ assert_that(p.cargo_process("build").arg("--features").arg("foo"),
+ execs().with_status(0));
+}
+
+#[test]
+fn everything_in_the_lockfile() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ f1 = ["d1/f1"]
+ f2 = ["d2"]
+
+ [dependencies.d1]
+ path = "d1"
+ [dependencies.d2]
+ path = "d2"
+ optional = true
+ [dependencies.d3]
+ path = "d3"
+ optional = true
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("d1/Cargo.toml", r#"
+ [package]
+ name = "d1"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ f1 = []
+ "#)
+ .file("d1/src/lib.rs", "")
+ .file("d2/Cargo.toml", r#"
+ [package]
+ name = "d2"
+ version = "0.0.2"
+ authors = []
+ "#)
+ .file("d2/src/lib.rs", "")
+ .file("d3/Cargo.toml", r#"
+ [package]
+ name = "d3"
+ version = "0.0.3"
+ authors = []
+
+ [features]
+ f3 = []
+ "#)
+ .file("d3/src/lib.rs", "");
+
+ assert_that(p.cargo_process("fetch"), execs().with_status(0));
+ let loc = p.root().join("Cargo.lock");
+ let mut lockfile = String::new();
+ t!(t!(File::open(&loc)).read_to_string(&mut lockfile));
+ assert!(lockfile.contains(r#"name = "d1""#), "d1 not found\n{}", lockfile);
+ assert!(lockfile.contains(r#"name = "d2""#), "d2 not found\n{}", lockfile);
+ assert!(lockfile.contains(r#"name = "d3""#), "d3 not found\n{}", lockfile);
+}
+
+#[test]
+fn no_rebuild_when_frobbing_default_feature() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ a = { path = "a" }
+ b = { path = "b" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ a = { path = "../a", features = ["f1"], default-features = false }
+ "#)
+ .file("b/src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.1.0"
+ authors = []
+
+ [features]
+ default = ["f1"]
+ f1 = []
+ "#)
+ .file("a/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+ assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
+ assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
+}
+
+#[test]
+fn unions_work_with_no_default_features() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ a = { path = "a" }
+ b = { path = "b" }
+ "#)
+ .file("src/lib.rs", r#"
+ extern crate a;
+ pub fn foo() { a::a(); }
+ "#)
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ a = { path = "../a", features = [], default-features = false }
+ "#)
+ .file("b/src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.1.0"
+ authors = []
+
+ [features]
+ default = ["f1"]
+ f1 = []
+ "#)
+ .file("a/src/lib.rs", r#"
+ #[cfg(feature = "f1")]
+ pub fn a() {}
+ "#);
+
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+ assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
+ assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
+}
+
+#[test]
+fn optional_and_dev_dep() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "test"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ foo = { path = "foo", optional = true }
+ [dev-dependencies]
+ foo = { path = "foo" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("foo/Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("foo/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] test v0.1.0 ([..])
+"));
+}
+
+#[test]
+fn activating_feature_activates_dep() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "test"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ foo = { path = "foo", optional = true }
+
+ [features]
+ a = ["foo/a"]
+ "#)
+ .file("src/lib.rs", "
+ extern crate foo;
+ pub fn bar() {
+ foo::bar();
+ }
+ ")
+ .file("foo/Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+
+ [features]
+ a = []
+ "#)
+ .file("foo/src/lib.rs", r#"
+ #[cfg(feature = "a")]
+ pub fn bar() {}
+ "#);
+
+ assert_that(p.cargo_process("build").arg("--features").arg("a").arg("-v"),
+ execs().with_status(0));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use cargotest::support::{project, execs};
+use hamcrest::assert_that;
+
+#[test]
+fn no_deps() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("src/main.rs", r#"
+ mod a; fn main() {}
+ "#)
+ .file("src/a.rs", "");
+
+ assert_that(p.cargo_process("fetch"),
+ execs().with_status(0).with_stdout(""));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::fs::{self, File};
+use std::io::prelude::*;
+
+use cargotest::sleep_ms;
+use cargotest::support::{project, execs, path2url};
+use cargotest::support::paths::CargoPathExt;
+use hamcrest::{assert_that, existing_file};
+
+#[test]
+fn modifying_and_moving() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("src/main.rs", r#"
+ mod a; fn main() {}
+ "#)
+ .file("src/a.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({dir})
+", dir = path2url(p.root()))));
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stdout(""));
+ p.root().move_into_the_past();
+ p.root().join("target").move_into_the_past();
+
+ File::create(&p.root().join("src/a.rs")).unwrap()
+ .write_all(b"#[allow(unused)]fn main() {}").unwrap();
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({dir})
+", dir = path2url(p.root()))));
+
+ fs::rename(&p.root().join("src/a.rs"), &p.root().join("src/b.rs")).unwrap();
+ assert_that(p.cargo("build"),
+ execs().with_status(101));
+}
+
+#[test]
+fn modify_only_some_files() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", "mod a;")
+ .file("src/a.rs", "")
+ .file("src/main.rs", r#"
+ mod b;
+ fn main() {}
+ "#)
+ .file("src/b.rs", "")
+ .file("tests/test.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({dir})
+", dir = path2url(p.root()))));
+ assert_that(p.cargo("test"),
+ execs().with_status(0));
+ sleep_ms(1000);
+
+ assert_that(&p.bin("foo"), existing_file());
+
+ let lib = p.root().join("src/lib.rs");
+ let bin = p.root().join("src/b.rs");
+
+ File::create(&lib).unwrap().write_all(b"invalid rust code").unwrap();
+ File::create(&bin).unwrap().write_all(b"#[allow(unused)]fn foo() {}").unwrap();
+ lib.move_into_the_past();
+
+ // Make sure the binary is rebuilt, not the lib
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({dir})
+", dir = path2url(p.root()))));
+ assert_that(&p.bin("foo"), existing_file());
+}
+
+#[test]
+fn rebuild_sub_package_then_while_package() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+
+ [dependencies.a]
+ path = "a"
+ [dependencies.b]
+ path = "b"
+ "#)
+ .file("src/lib.rs", "extern crate a; extern crate b;")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ authors = []
+ version = "0.0.1"
+ [dependencies.b]
+ path = "../b"
+ "#)
+ .file("a/src/lib.rs", "extern crate b;")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("b/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0));
+
+ File::create(&p.root().join("b/src/lib.rs")).unwrap().write_all(br#"
+ pub fn b() {}
+ "#).unwrap();
+
+ assert_that(p.cargo("build").arg("-pb"),
+ execs().with_status(0));
+
+ File::create(&p.root().join("src/lib.rs")).unwrap().write_all(br#"
+ extern crate a;
+ extern crate b;
+ pub fn toplevel() {}
+ "#).unwrap();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn changing_features_is_ok() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+
+ [features]
+ foo = []
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0)
+ .with_stderr("\
+[..]Compiling foo v0.0.1 ([..])
+"));
+
+ assert_that(p.cargo("build").arg("--features").arg("foo"),
+ execs().with_status(0)
+ .with_stderr("\
+[..]Compiling foo v0.0.1 ([..])
+"));
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0)
+ .with_stderr("\
+[..]Compiling foo v0.0.1 ([..])
+"));
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0)
+ .with_stdout(""));
+}
+
+#[test]
+fn rebuild_tests_if_lib_changes() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn foo() {}")
+ .file("tests/foo.rs", r#"
+ extern crate foo;
+ #[test]
+ fn test() { foo::foo(); }
+ "#);
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0));
+ assert_that(p.cargo("test"),
+ execs().with_status(0));
+
+ File::create(&p.root().join("src/lib.rs")).unwrap();
+ p.root().move_into_the_past();
+ p.root().join("target").move_into_the_past();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+ assert_that(p.cargo("test").arg("-v"),
+ execs().with_status(101));
+}
+
+#[test]
+fn no_rebuild_transitive_target_deps() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ a = { path = "a" }
+ [dev-dependencies]
+ b = { path = "b" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("tests/foo.rs", "")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [target.foo.dependencies]
+ c = { path = "../c" }
+ "#)
+ .file("a/src/lib.rs", "")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ c = { path = "../c" }
+ "#)
+ .file("b/src/lib.rs", "")
+ .file("c/Cargo.toml", r#"
+ [package]
+ name = "c"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("c/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0));
+ assert_that(p.cargo("test").arg("--no-run"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] c v0.0.1 ([..])
+[COMPILING] b v0.0.1 ([..])
+[COMPILING] foo v0.0.1 ([..])
+"));
+}
+
+#[test]
+fn rerun_if_changed_in_dep() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ a = { path = "a" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("a/build.rs", r#"
+ fn main() {
+ println!("cargo:rerun-if-changed=build.rs");
+ }
+ "#)
+ .file("a/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0));
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stdout(""));
+}
+
+#[test]
+fn same_build_dir_cached_packages() {
+ let p = project("foo")
+ .file("a1/Cargo.toml", r#"
+ [package]
+ name = "a1"
+ version = "0.0.1"
+ authors = []
+ [dependencies]
+ b = { path = "../b" }
+ "#)
+ .file("a1/src/lib.rs", "")
+ .file("a2/Cargo.toml", r#"
+ [package]
+ name = "a2"
+ version = "0.0.1"
+ authors = []
+ [dependencies]
+ b = { path = "../b" }
+ "#)
+ .file("a2/src/lib.rs", "")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.0.1"
+ authors = []
+ [dependencies]
+ c = { path = "../c" }
+ "#)
+ .file("b/src/lib.rs", "")
+ .file("c/Cargo.toml", r#"
+ [package]
+ name = "c"
+ version = "0.0.1"
+ authors = []
+ [dependencies]
+ d = { path = "../d" }
+ "#)
+ .file("c/src/lib.rs", "")
+ .file("d/Cargo.toml", r#"
+ [package]
+ name = "d"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("d/src/lib.rs", "")
+ .file(".cargo/config", r#"
+ [build]
+ target-dir = "./target"
+ "#);
+ p.build();
+
+ assert_that(p.cargo("build").cwd(p.root().join("a1")),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] d v0.0.1 ({dir}/d)
+[COMPILING] c v0.0.1 ({dir}/c)
+[COMPILING] b v0.0.1 ({dir}/b)
+[COMPILING] a1 v0.0.1 ({dir}/a1)
+", dir = p.url())));
+ assert_that(p.cargo("build").cwd(p.root().join("a2")),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] a2 v0.0.1 ({dir}/a2)
+", dir = p.url())));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::fs::{self, File};
+use std::io::prelude::*;
+
+use cargotest::support::{project, execs};
+use hamcrest::{assert_that, existing_file, is_not};
+
+#[test]
+fn adding_and_removing_packages() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("bar/src/lib.rs", "");
+
+ assert_that(p.cargo_process("generate-lockfile"),
+ execs().with_status(0));
+
+ let lockfile = p.root().join("Cargo.lock");
+ let toml = p.root().join("Cargo.toml");
+ let mut lock1 = String::new();
+ File::open(&lockfile).unwrap().read_to_string(&mut lock1).unwrap();
+
+ // add a dep
+ File::create(&toml).unwrap().write_all(br#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+
+ [dependencies.bar]
+ path = "bar"
+ "#).unwrap();
+ assert_that(p.cargo("generate-lockfile"),
+ execs().with_status(0));
+ let mut lock2 = String::new();
+ File::open(&lockfile).unwrap().read_to_string(&mut lock2).unwrap();
+ assert!(lock1 != lock2);
+
+ // change the dep
+ File::create(&p.root().join("bar/Cargo.toml")).unwrap().write_all(br#"
+ [package]
+ name = "bar"
+ authors = []
+ version = "0.0.2"
+ "#).unwrap();
+ assert_that(p.cargo("generate-lockfile"),
+ execs().with_status(0));
+ let mut lock3 = String::new();
+ File::open(&lockfile).unwrap().read_to_string(&mut lock3).unwrap();
+ assert!(lock1 != lock3);
+ assert!(lock2 != lock3);
+
+ // remove the dep
+ println!("lock4");
+ File::create(&toml).unwrap().write_all(br#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+ "#).unwrap();
+ assert_that(p.cargo("generate-lockfile"),
+ execs().with_status(0));
+ let mut lock4 = String::new();
+ File::open(&lockfile).unwrap().read_to_string(&mut lock4).unwrap();
+ assert_eq!(lock1, lock4);
+}
+
+#[test]
+fn preserve_metadata() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("bar/src/lib.rs", "");
+
+ assert_that(p.cargo_process("generate-lockfile"),
+ execs().with_status(0));
+
+ let metadata = r#"
+[metadata]
+bar = "baz"
+foo = "bar"
+"#;
+ let lockfile = p.root().join("Cargo.lock");
+ {
+ let mut lock = String::new();
+ File::open(&lockfile).unwrap().read_to_string(&mut lock).unwrap();
+ let data = lock + metadata;
+ File::create(&lockfile).unwrap().write_all(data.as_bytes()).unwrap();
+ }
+
+ // Build and make sure the metadata is still there
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+ let mut lock = String::new();
+ File::open(&lockfile).unwrap().read_to_string(&mut lock).unwrap();
+ assert!(lock.contains(metadata.trim()), "{}", lock);
+
+ // Update and make sure the metadata is still there
+ assert_that(p.cargo("update"),
+ execs().with_status(0));
+ let mut lock = String::new();
+ File::open(&lockfile).unwrap().read_to_string(&mut lock).unwrap();
+ assert!(lock.contains(metadata.trim()), "{}", lock);
+}
+
+#[test]
+fn preserve_line_endings_issue_2076() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("bar/src/lib.rs", "");
+
+ let lockfile = p.root().join("Cargo.lock");
+ assert_that(p.cargo_process("generate-lockfile"),
+ execs().with_status(0));
+ assert_that(&lockfile,
+ existing_file());
+ assert_that(p.cargo("generate-lockfile"),
+ execs().with_status(0));
+
+ let mut lock0 = String::new();
+ {
+ File::open(&lockfile).unwrap().read_to_string(&mut lock0).unwrap();
+ }
+
+ assert!(lock0.starts_with("[root]\n"));
+
+ let lock1 = lock0.replace("\n", "\r\n");
+ {
+ File::create(&lockfile).unwrap().write_all(lock1.as_bytes()).unwrap();
+ }
+
+ assert_that(p.cargo("generate-lockfile"),
+ execs().with_status(0));
+
+ let mut lock2 = String::new();
+ {
+ File::open(&lockfile).unwrap().read_to_string(&mut lock2).unwrap();
+ }
+
+ assert!(lock2.starts_with("[root]\r\n"));
+ assert_eq!(lock1, lock2);
+}
+
+#[test]
+fn cargo_update_generate_lockfile() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ let lockfile = p.root().join("Cargo.lock");
+ assert_that(&lockfile, is_not(existing_file()));
+ assert_that(p.cargo_process("update"), execs().with_status(0).with_stdout(""));
+ assert_that(&lockfile, existing_file());
+
+ fs::remove_file(p.root().join("Cargo.lock")).unwrap();
+
+ assert_that(&lockfile, is_not(existing_file()));
+ assert_that(p.cargo("update"), execs().with_status(0).with_stdout(""));
+ assert_that(&lockfile, existing_file());
+
+}
--- /dev/null
+extern crate cargo;
+extern crate cargotest;
+extern crate git2;
+extern crate hamcrest;
+
+use std::fs::{self, File};
+use std::io::prelude::*;
+use std::path::Path;
+
+use cargo::util::process;
+use cargotest::{sleep_ms, RUSTC};
+use cargotest::support::paths::{self, CargoPathExt};
+use cargotest::support::{git, project, execs, main_file, path2url};
+use hamcrest::{assert_that,existing_file};
+
+#[test]
+fn cargo_compile_simple_git_dep() {
+ let project = project("foo");
+ let git_project = git::new("dep1", |project| {
+ project
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+
+ [lib]
+
+ name = "dep1"
+ "#)
+ .file("src/dep1.rs", r#"
+ pub fn hello() -> &'static str {
+ "hello world"
+ }
+ "#)
+ }).unwrap();
+
+ let project = project
+ .file("Cargo.toml", &format!(r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.dep1]
+
+ git = '{}'
+
+ [[bin]]
+
+ name = "foo"
+ "#, git_project.url()))
+ .file("src/foo.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]));
+
+ let root = project.root();
+ let git_root = git_project.root();
+
+ assert_that(project.cargo_process("build"),
+ execs()
+ .with_stderr(&format!("[UPDATING] git repository `{}`\n\
+ [COMPILING] dep1 v0.5.0 ({}#[..])\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ path2url(git_root.clone()),
+ path2url(git_root),
+ path2url(root))));
+
+ assert_that(&project.bin("foo"), existing_file());
+
+ assert_that(
+ process(&project.bin("foo")),
+ execs().with_stdout("hello world\n"));
+}
+
+#[test]
+fn cargo_compile_git_dep_branch() {
+ let project = project("foo");
+ let git_project = git::new("dep1", |project| {
+ project
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+
+ [lib]
+
+ name = "dep1"
+ "#)
+ .file("src/dep1.rs", r#"
+ pub fn hello() -> &'static str {
+ "hello world"
+ }
+ "#)
+ }).unwrap();
+
+ // Make a new branch based on the current HEAD commit
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ let head = repo.head().unwrap().target().unwrap();
+ let head = repo.find_commit(head).unwrap();
+ repo.branch("branchy", &head, true).unwrap();
+
+ let project = project
+ .file("Cargo.toml", &format!(r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.dep1]
+
+ git = '{}'
+ branch = "branchy"
+
+ [[bin]]
+
+ name = "foo"
+ "#, git_project.url()))
+ .file("src/foo.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]));
+
+ let root = project.root();
+ let git_root = git_project.root();
+
+ assert_that(project.cargo_process("build"),
+ execs()
+ .with_stderr(&format!("[UPDATING] git repository `{}`\n\
+ [COMPILING] dep1 v0.5.0 ({}?branch=branchy#[..])\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ path2url(git_root.clone()),
+ path2url(git_root),
+ path2url(root))));
+
+ assert_that(&project.bin("foo"), existing_file());
+
+ assert_that(
+ process(&project.bin("foo")),
+ execs().with_stdout("hello world\n"));
+}
+
+#[test]
+fn cargo_compile_git_dep_tag() {
+ let project = project("foo");
+ let git_project = git::new("dep1", |project| {
+ project
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+
+ [lib]
+
+ name = "dep1"
+ "#)
+ .file("src/dep1.rs", r#"
+ pub fn hello() -> &'static str {
+ "hello world"
+ }
+ "#)
+ }).unwrap();
+
+ // Make a tag corresponding to the current HEAD
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ let head = repo.head().unwrap().target().unwrap();
+ repo.tag("v0.1.0",
+ &repo.find_object(head, None).unwrap(),
+ &repo.signature().unwrap(),
+ "make a new tag",
+ false).unwrap();
+
+ let project = project
+ .file("Cargo.toml", &format!(r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.dep1]
+
+ git = '{}'
+ tag = "v0.1.0"
+
+ [[bin]]
+
+ name = "foo"
+ "#, git_project.url()))
+ .file("src/foo.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]));
+
+ let root = project.root();
+ let git_root = git_project.root();
+
+ assert_that(project.cargo_process("build"),
+ execs()
+ .with_stderr(&format!("[UPDATING] git repository `{}`\n\
+ [COMPILING] dep1 v0.5.0 ({}?tag=v0.1.0#[..])\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ path2url(git_root.clone()),
+ path2url(git_root),
+ path2url(root))));
+
+ assert_that(&project.bin("foo"), existing_file());
+
+ assert_that(process(&project.bin("foo")),
+ execs().with_stdout("hello world\n"));
+
+ assert_that(project.cargo("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn cargo_compile_with_nested_paths() {
+ let git_project = git::new("dep1", |project| {
+ project
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+
+ [dependencies.dep2]
+
+ version = "0.5.0"
+ path = "vendor/dep2"
+
+ [lib]
+
+ name = "dep1"
+ "#)
+ .file("src/dep1.rs", r#"
+ extern crate dep2;
+
+ pub fn hello() -> &'static str {
+ dep2::hello()
+ }
+ "#)
+ .file("vendor/dep2/Cargo.toml", r#"
+ [project]
+
+ name = "dep2"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+
+ [lib]
+
+ name = "dep2"
+ "#)
+ .file("vendor/dep2/src/dep2.rs", r#"
+ pub fn hello() -> &'static str {
+ "hello world"
+ }
+ "#)
+ }).unwrap();
+
+ let p = project("parent")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+
+ name = "parent"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.dep1]
+
+ version = "0.5.0"
+ git = '{}'
+
+ [[bin]]
+
+ name = "parent"
+ "#, git_project.url()))
+ .file("src/parent.rs",
+ &main_file(r#""{}", dep1::hello()"#, &["dep1"]));
+
+ p.cargo_process("build")
+ .exec_with_output()
+ .unwrap();
+
+ assert_that(&p.bin("parent"), existing_file());
+
+ assert_that(process(&p.bin("parent")),
+ execs().with_stdout("hello world\n"));
+}
+
+#[test]
+fn cargo_compile_with_meta_package() {
+ let git_project = git::new("meta-dep", |project| {
+ project
+ .file("dep1/Cargo.toml", r#"
+ [project]
+
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+
+ [lib]
+
+ name = "dep1"
+ "#)
+ .file("dep1/src/dep1.rs", r#"
+ pub fn hello() -> &'static str {
+ "this is dep1"
+ }
+ "#)
+ .file("dep2/Cargo.toml", r#"
+ [project]
+
+ name = "dep2"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+
+ [lib]
+
+ name = "dep2"
+ "#)
+ .file("dep2/src/dep2.rs", r#"
+ pub fn hello() -> &'static str {
+ "this is dep2"
+ }
+ "#)
+ }).unwrap();
+
+ let p = project("parent")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+
+ name = "parent"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.dep1]
+
+ version = "0.5.0"
+ git = '{}'
+
+ [dependencies.dep2]
+
+ version = "0.5.0"
+ git = '{}'
+
+ [[bin]]
+
+ name = "parent"
+ "#, git_project.url(), git_project.url()))
+ .file("src/parent.rs",
+ &main_file(r#""{} {}", dep1::hello(), dep2::hello()"#, &["dep1", "dep2"]));
+
+ p.cargo_process("build")
+ .exec_with_output()
+ .unwrap();
+
+ assert_that(&p.bin("parent"), existing_file());
+
+ assert_that(process(&p.bin("parent")),
+ execs().with_stdout("this is dep1 this is dep2\n"));
+}
+
+#[test]
+fn cargo_compile_with_short_ssh_git() {
+ let url = "git@github.com:a/dep";
+
+ let project = project("project")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.dep]
+
+ git = "{}"
+
+ [[bin]]
+
+ name = "foo"
+ "#, url))
+ .file("src/foo.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]));
+
+ assert_that(project.cargo_process("build"),
+ execs()
+ .with_stdout("")
+ .with_stderr(&format!("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ invalid url `{}`: relative URL without a base
+", url)));
+}
+
+#[test]
+fn two_revs_same_deps() {
+ let bar = git::new("meta-dep", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
+ }).unwrap();
+
+ let repo = git2::Repository::open(&bar.root()).unwrap();
+ let rev1 = repo.revparse_single("HEAD").unwrap().id();
+
+ // Commit the changes and make sure we trigger a recompile
+ File::create(&bar.root().join("src/lib.rs")).unwrap().write_all(br#"
+ pub fn bar() -> i32 { 2 }
+ "#).unwrap();
+ git::add(&repo);
+ let rev2 = git::commit(&repo);
+
+ let foo = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+
+ [dependencies.bar]
+ git = '{}'
+ rev = "{}"
+
+ [dependencies.baz]
+ path = "../baz"
+ "#, bar.url(), rev1))
+ .file("src/main.rs", r#"
+ extern crate bar;
+ extern crate baz;
+
+ fn main() {
+ assert_eq!(bar::bar(), 1);
+ assert_eq!(baz::baz(), 2);
+ }
+ "#);
+
+ let baz = project("baz")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "baz"
+ version = "0.0.0"
+ authors = []
+
+ [dependencies.bar]
+ git = '{}'
+ rev = "{}"
+ "#, bar.url(), rev2))
+ .file("src/lib.rs", r#"
+ extern crate bar;
+ pub fn baz() -> i32 { bar::bar() }
+ "#);
+
+ baz.build();
+
+ assert_that(foo.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+ assert_that(&foo.bin("foo"), existing_file());
+ assert_that(foo.process(&foo.bin("foo")), execs().with_status(0));
+}
+
+#[test]
+fn recompilation() {
+ let git_project = git::new("bar", |project| {
+ project
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+
+ [lib]
+ name = "bar"
+ "#)
+ .file("src/bar.rs", r#"
+ pub fn bar() {}
+ "#)
+ }).unwrap();
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+
+ version = "0.5.0"
+ git = '{}'
+
+ [[bin]]
+
+ name = "foo"
+ "#, git_project.url()))
+ .file("src/foo.rs",
+ &main_file(r#""{:?}", bar::bar()"#, &["bar"]));
+
+ // First time around we should compile both foo and bar
+ assert_that(p.cargo_process("build"),
+ execs().with_stderr(&format!("[UPDATING] git repository `{}`\n\
+ [COMPILING] bar v0.5.0 ({}#[..])\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ git_project.url(),
+ git_project.url(),
+ p.url())));
+
+ // Don't recompile the second time
+ assert_that(p.cargo("build"),
+ execs().with_stdout(""));
+
+ // Modify a file manually, shouldn't trigger a recompile
+ File::create(&git_project.root().join("src/bar.rs")).unwrap().write_all(br#"
+ pub fn bar() { println!("hello!"); }
+ "#).unwrap();
+
+ assert_that(p.cargo("build"),
+ execs().with_stdout(""));
+
+ assert_that(p.cargo("update"),
+ execs().with_stderr(&format!("[UPDATING] git repository `{}`",
+ git_project.url())));
+
+ assert_that(p.cargo("build"),
+ execs().with_stdout(""));
+
+ // Commit the changes and make sure we don't trigger a recompile because the
+ // lockfile says not to change
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ git::add(&repo);
+ git::commit(&repo);
+
+ println!("compile after commit");
+ assert_that(p.cargo("build"),
+ execs().with_stdout(""));
+ p.root().move_into_the_past();
+
+ // Update the dependency and carry on!
+ assert_that(p.cargo("update"),
+ execs().with_stderr(&format!("[UPDATING] git repository `{}`\n\
+ [UPDATING] bar v0.5.0 ([..]) -> #[..]\n\
+ ",
+ git_project.url())));
+ println!("going for the last compile");
+ assert_that(p.cargo("build"),
+ execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}#[..])\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ git_project.url(),
+ p.url())));
+
+ // Make sure clean only cleans one dep
+ assert_that(p.cargo("clean")
+ .arg("-p").arg("foo"),
+ execs().with_stdout(""));
+ assert_that(p.cargo("build"),
+ execs().with_stderr(&format!("[COMPILING] foo v0.5.0 ({})\n",
+ p.url())));
+}
+
+#[test]
+fn update_with_shared_deps() {
+ let git_project = git::new("bar", |project| {
+ project
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+
+ [lib]
+ name = "bar"
+ "#)
+ .file("src/bar.rs", r#"
+ pub fn bar() {}
+ "#)
+ }).unwrap();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.dep1]
+ path = "dep1"
+ [dependencies.dep2]
+ path = "dep2"
+ "#)
+ .file("src/main.rs", r#"
+ extern crate dep1;
+ extern crate dep2;
+ fn main() {}
+ "#)
+ .file("dep1/Cargo.toml", &format!(r#"
+ [package]
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+ version = "0.5.0"
+ git = '{}'
+ "#, git_project.url()))
+ .file("dep1/src/lib.rs", "")
+ .file("dep2/Cargo.toml", &format!(r#"
+ [package]
+ name = "dep2"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+ version = "0.5.0"
+ git = '{}'
+ "#, git_project.url()))
+ .file("dep2/src/lib.rs", "");
+
+ // First time around we should compile both foo and bar
+ assert_that(p.cargo_process("build"),
+ execs().with_stderr(&format!("\
+[UPDATING] git repository `{git}`
+[COMPILING] bar v0.5.0 ({git}#[..])
+[COMPILING] [..] v0.5.0 ([..])
+[COMPILING] [..] v0.5.0 ([..])
+[COMPILING] foo v0.5.0 ({dir})\n", git = git_project.url(), dir = p.url())));
+
+ // Modify a file manually, and commit it
+ File::create(&git_project.root().join("src/bar.rs")).unwrap().write_all(br#"
+ pub fn bar() { println!("hello!"); }
+ "#).unwrap();
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ let old_head = repo.head().unwrap().target().unwrap();
+ git::add(&repo);
+ git::commit(&repo);
+
+ sleep_ms(1000);
+
+ // By default, not transitive updates
+ println!("dep1 update");
+ assert_that(p.cargo("update")
+ .arg("-p").arg("dep1"),
+ execs().with_stdout(""));
+
+ // Don't do anything bad on a weird --precise argument
+ println!("bar bad precise update");
+ assert_that(p.cargo("update")
+ .arg("-p").arg("bar")
+ .arg("--precise").arg("0.1.2"),
+ execs().with_status(101).with_stderr("\
+[UPDATING] git repository [..]
+[ERROR] Unable to update [..]
+
+To learn more, run the command again with --verbose.
+"));
+
+ // Specifying a precise rev to the old rev shouldn't actually update
+ // anything because we already have the rev in the db.
+ println!("bar precise update");
+ assert_that(p.cargo("update")
+ .arg("-p").arg("bar")
+ .arg("--precise").arg(&old_head.to_string()),
+ execs().with_stdout(""));
+
+ // Updating aggressively should, however, update the repo.
+ println!("dep1 aggressive update");
+ assert_that(p.cargo("update")
+ .arg("-p").arg("dep1")
+ .arg("--aggressive"),
+ execs().with_stderr(&format!("[UPDATING] git repository `{}`\n\
+ [UPDATING] bar v0.5.0 ([..]) -> #[..]\n\
+ ", git_project.url())));
+
+ // Make sure we still only compile one version of the git repo
+ println!("build");
+ assert_that(p.cargo("build"),
+ execs().with_stderr(&format!("\
+[COMPILING] bar v0.5.0 ({git}#[..])
+[COMPILING] [..] v0.5.0 ({dir}[..]dep[..])
+[COMPILING] [..] v0.5.0 ({dir}[..]dep[..])
+[COMPILING] foo v0.5.0 ({dir})\n",
+ git = git_project.url(), dir = p.url())));
+
+ // We should be able to update transitive deps
+ assert_that(p.cargo("update").arg("-p").arg("bar"),
+ execs().with_stderr(&format!("[UPDATING] git repository `{}`",
+ git_project.url())));
+}
+
+#[test]
+fn dep_with_submodule() {
+ let project = project("foo");
+ let git_project = git::new("dep1", |project| {
+ project
+ .file("Cargo.toml", r#"
+ [package]
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+ "#)
+ }).unwrap();
+ let git_project2 = git::new("dep2", |project| {
+ project.file("lib.rs", "pub fn dep() {}")
+ }).unwrap();
+
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ let url = path2url(git_project2.root()).to_string();
+ git::add_submodule(&repo, &url, Path::new("src"));
+ git::commit(&repo);
+
+ let project = project
+ .file("Cargo.toml", &format!(r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.dep1]
+
+ git = '{}'
+ "#, git_project.url()))
+ .file("src/lib.rs", "
+ extern crate dep1;
+ pub fn foo() { dep1::dep() }
+ ");
+
+ assert_that(project.cargo_process("build"),
+ execs().with_stderr("\
+[UPDATING] git repository [..]
+[COMPILING] dep1 [..]
+[COMPILING] foo [..]").with_status(0));
+}
+
+#[test]
+fn two_deps_only_update_one() {
+ let project = project("foo");
+ let git1 = git::new("dep1", |project| {
+ project
+ .file("Cargo.toml", r#"
+ [package]
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+ "#)
+ .file("src/lib.rs", "")
+ }).unwrap();
+ let git2 = git::new("dep2", |project| {
+ project
+ .file("Cargo.toml", r#"
+ [package]
+ name = "dep2"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+ "#)
+ .file("src/lib.rs", "")
+ }).unwrap();
+
+ let project = project
+ .file("Cargo.toml", &format!(r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.dep1]
+ git = '{}'
+ [dependencies.dep2]
+ git = '{}'
+ "#, git1.url(), git2.url()))
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(project.cargo_process("build"),
+ execs()
+ .with_stderr(&format!("[UPDATING] git repository `[..]`\n\
+ [UPDATING] git repository `[..]`\n\
+ [COMPILING] [..] v0.5.0 ([..])\n\
+ [COMPILING] [..] v0.5.0 ([..])\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ project.url())));
+
+ File::create(&git1.root().join("src/lib.rs")).unwrap().write_all(br#"
+ pub fn foo() {}
+ "#).unwrap();
+ let repo = git2::Repository::open(&git1.root()).unwrap();
+ git::add(&repo);
+ git::commit(&repo);
+
+ assert_that(project.cargo("update")
+ .arg("-p").arg("dep1"),
+ execs()
+ .with_stderr(&format!("[UPDATING] git repository `{}`\n\
+ [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
+ ", git1.url())));
+}
+
+#[test]
+fn stale_cached_version() {
+ let bar = git::new("meta-dep", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
+ }).unwrap();
+
+ // Update the git database in the cache with the current state of the git
+ // repo
+ let foo = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+
+ [dependencies.bar]
+ git = '{}'
+ "#, bar.url()))
+ .file("src/main.rs", r#"
+ extern crate bar;
+
+ fn main() { assert_eq!(bar::bar(), 1) }
+ "#);
+
+ assert_that(foo.cargo_process("build"), execs().with_status(0));
+ assert_that(foo.process(&foo.bin("foo")), execs().with_status(0));
+
+ // Update the repo, and simulate someone else updating the lockfile and then
+ // us pulling it down.
+ File::create(&bar.root().join("src/lib.rs")).unwrap().write_all(br#"
+ pub fn bar() -> i32 { 1 + 0 }
+ "#).unwrap();
+ let repo = git2::Repository::open(&bar.root()).unwrap();
+ git::add(&repo);
+ git::commit(&repo);
+
+ sleep_ms(1000);
+
+ let rev = repo.revparse_single("HEAD").unwrap().id();
+
+ File::create(&foo.root().join("Cargo.lock")).unwrap().write_all(format!(r#"
+ [root]
+ name = "foo"
+ version = "0.0.0"
+ dependencies = [
+ 'bar 0.0.0 (git+{url}#{hash})'
+ ]
+
+ [[package]]
+ name = "bar"
+ version = "0.0.0"
+ source = 'git+{url}#{hash}'
+ "#, url = bar.url(), hash = rev).as_bytes()).unwrap();
+
+ // Now build!
+ assert_that(foo.cargo("build"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[UPDATING] git repository `{bar}`
+[COMPILING] bar v0.0.0 ({bar}#[..])
+[COMPILING] foo v0.0.0 ({foo})
+", bar = bar.url(), foo = foo.url())));
+ assert_that(foo.process(&foo.bin("foo")), execs().with_status(0));
+}
+
+#[test]
+fn dep_with_changed_submodule() {
+ let project = project("foo");
+ let git_project = git::new("dep1", |project| {
+ project
+ .file("Cargo.toml", r#"
+ [package]
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+ "#)
+ }).unwrap();
+
+ let git_project2 = git::new("dep2", |project| {
+ project
+ .file("lib.rs", "pub fn dep() -> &'static str { \"project2\" }")
+ }).unwrap();
+
+ let git_project3 = git::new("dep3", |project| {
+ project
+ .file("lib.rs", "pub fn dep() -> &'static str { \"project3\" }")
+ }).unwrap();
+
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ let mut sub = git::add_submodule(&repo, &git_project2.url().to_string(),
+ &Path::new("src"));
+ git::commit(&repo);
+
+ let project = project
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ [dependencies.dep1]
+ git = '{}'
+ "#, git_project.url()))
+ .file("src/main.rs", "
+ extern crate dep1;
+ pub fn main() { println!(\"{}\", dep1::dep()) }
+ ");
+
+ println!("first run");
+ assert_that(project.cargo_process("run"), execs()
+ .with_stderr("[UPDATING] git repository `[..]`\n\
+ [COMPILING] dep1 v0.5.0 ([..])\n\
+ [COMPILING] foo v0.5.0 ([..])\n\
+ [RUNNING] `target[..]foo[..]`\n")
+ .with_stdout("project2\n")
+ .with_status(0));
+
+ File::create(&git_project.root().join(".gitmodules")).unwrap()
+ .write_all(format!("[submodule \"src\"]\n\tpath = src\n\turl={}",
+ git_project3.url()).as_bytes()).unwrap();
+
+ // Sync the submodule and reset it to the new remote.
+ sub.sync().unwrap();
+ {
+ let subrepo = sub.open().unwrap();
+ subrepo.remote_add_fetch("origin",
+ "refs/heads/*:refs/heads/*").unwrap();
+ subrepo.remote_set_url("origin",
+ &git_project3.url().to_string()).unwrap();
+ let mut origin = subrepo.find_remote("origin").unwrap();
+ origin.fetch(&[], None, None).unwrap();
+ let id = subrepo.refname_to_id("refs/remotes/origin/master").unwrap();
+ let obj = subrepo.find_object(id, None).unwrap();
+ subrepo.reset(&obj, git2::ResetType::Hard, None).unwrap();
+ }
+ sub.add_to_index(true).unwrap();
+ git::add(&repo);
+ git::commit(&repo);
+
+ sleep_ms(1000);
+ // Update the dependency and carry on!
+ println!("update");
+ assert_that(project.cargo("update").arg("-v"),
+ execs()
+ .with_stderr("")
+ .with_stderr(&format!("[UPDATING] git repository `{}`\n\
+ [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
+ ", git_project.url())));
+
+ println!("last run");
+ assert_that(project.cargo("run"), execs()
+ .with_stderr("[COMPILING] dep1 v0.5.0 ([..])\n\
+ [COMPILING] foo v0.5.0 ([..])\n\
+ [RUNNING] `target[..]foo[..]`\n")
+ .with_stdout("project3\n")
+ .with_status(0));
+}
+
+#[test]
+fn dev_deps_with_testing() {
+ let p2 = git::new("bar", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn gimme() -> &'static str { "zoidberg" }
+ "#)
+ }).unwrap();
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dev-dependencies.bar]
+ version = "0.5.0"
+ git = '{}'
+ "#, p2.url()))
+ .file("src/main.rs", r#"
+ fn main() {}
+
+ #[cfg(test)]
+ mod tests {
+ extern crate bar;
+ #[test] fn foo() { bar::gimme(); }
+ }
+ "#);
+
+ // Generate a lockfile which did not use `bar` to compile, but had to update
+ // `bar` to generate the lockfile
+ assert_that(p.cargo_process("build"),
+ execs().with_stderr(&format!("\
+[UPDATING] git repository `{bar}`
+[COMPILING] foo v0.5.0 ({url})
+", url = p.url(), bar = p2.url())));
+
+ // Make sure we use the previous resolution of `bar` instead of updating it
+ // a second time.
+ assert_that(p.cargo("test"),
+ execs().with_stderr("\
+[COMPILING] [..] v0.5.0 ([..])
+[COMPILING] [..] v0.5.0 ([..]
+[RUNNING] target[..]foo-[..]")
+ .with_stdout("
+running 1 test
+test tests::foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn git_build_cmd_freshness() {
+ let foo = git::new("foo", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("build.rs", "fn main() {}")
+ .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
+ .file(".gitignore", "
+ src/bar.rs
+ ")
+ }).unwrap();
+ foo.root().move_into_the_past();
+
+ sleep_ms(1000);
+
+ assert_that(foo.cargo("build"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.0 ({url})
+", url = foo.url())));
+
+ // Smoke test to make sure it doesn't compile again
+ println!("first pass");
+ assert_that(foo.cargo("build"),
+ execs().with_status(0)
+ .with_stdout(""));
+
+ // Modify an ignored file and make sure we don't rebuild
+ println!("second pass");
+ File::create(&foo.root().join("src/bar.rs")).unwrap();
+ assert_that(foo.cargo("build"),
+ execs().with_status(0)
+ .with_stdout(""));
+}
+
+#[test]
+fn git_name_not_always_needed() {
+ let p2 = git::new("bar", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn gimme() -> &'static str { "zoidberg" }
+ "#)
+ }).unwrap();
+
+ let repo = git2::Repository::open(&p2.root()).unwrap();
+ let mut cfg = repo.config().unwrap();
+ let _ = cfg.remove("user.name");
+ let _ = cfg.remove("user.email");
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dev-dependencies.bar]
+ git = '{}'
+ "#, p2.url()))
+ .file("src/main.rs", "fn main() {}");
+
+ // Generate a lockfile which did not use `bar` to compile, but had to update
+ // `bar` to generate the lockfile
+ assert_that(p.cargo_process("build"),
+ execs().with_stderr(&format!("\
+[UPDATING] git repository `{bar}`
+[COMPILING] foo v0.5.0 ({url})
+", url = p.url(), bar = p2.url())));
+}
+
+#[test]
+fn git_repo_changing_no_rebuild() {
+ let bar = git::new("bar", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
+ }).unwrap();
+
+ // Lock p1 to the first rev in the git repo
+ let p1 = project("p1")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "p1"
+ version = "0.5.0"
+ authors = []
+ build = 'build.rs'
+ [dependencies.bar]
+ git = '{}'
+ "#, bar.url()))
+ .file("src/main.rs", "fn main() {}")
+ .file("build.rs", "fn main() {}");
+ p1.build();
+ p1.root().move_into_the_past();
+ assert_that(p1.cargo("build"),
+ execs().with_stderr(&format!("\
+[UPDATING] git repository `{bar}`
+[COMPILING] [..]
+[COMPILING] [..]
+", bar = bar.url())));
+
+ // Make a commit to lock p2 to a different rev
+ File::create(&bar.root().join("src/lib.rs")).unwrap().write_all(br#"
+ pub fn bar() -> i32 { 2 }
+ "#).unwrap();
+ let repo = git2::Repository::open(&bar.root()).unwrap();
+ git::add(&repo);
+ git::commit(&repo);
+
+ // Lock p2 to the second rev
+ let p2 = project("p2")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "p2"
+ version = "0.5.0"
+ authors = []
+ [dependencies.bar]
+ git = '{}'
+ "#, bar.url()))
+ .file("src/main.rs", "fn main() {}");
+ assert_that(p2.cargo_process("build"),
+ execs().with_stderr(&format!("\
+[UPDATING] git repository `{bar}`
+[COMPILING] [..]
+[COMPILING] [..]
+", bar = bar.url())));
+
+ // And now for the real test! Make sure that p1 doesn't get rebuilt
+ // even though the git repo has changed.
+ assert_that(p1.cargo("build"),
+ execs().with_stdout(""));
+}
+
+#[test]
+fn git_dep_build_cmd() {
+ let p = git::new("foo", |project| {
+ project.file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+
+ version = "0.5.0"
+ path = "bar"
+
+ [[bin]]
+
+ name = "foo"
+ "#)
+ .file("src/foo.rs",
+ &main_file(r#""{}", bar::gimme()"#, &["bar"]))
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ build = "build.rs"
+
+ [lib]
+
+ name = "bar"
+ "#)
+ .file("bar/src/bar.rs.in", r#"
+ pub fn gimme() -> i32 { 0 }
+ "#)
+ .file("bar/build.rs", r#"
+ use std::fs;
+ fn main() {
+ fs::copy("src/bar.rs.in", "src/bar.rs").unwrap();
+ }
+ "#)
+ }).unwrap();
+
+ p.root().join("bar").move_into_the_past();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("0\n"));
+
+ // Touching bar.rs.in should cause the `build` command to run again.
+ fs::File::create(&p.root().join("bar/src/bar.rs.in")).unwrap()
+ .write_all(b"pub fn gimme() -> i32 { 1 }").unwrap();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("1\n"));
+}
+
+#[test]
+fn fetch_downloads() {
+ let bar = git::new("bar", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
+ }).unwrap();
+
+ let p = project("p1")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "p1"
+ version = "0.5.0"
+ authors = []
+ [dependencies.bar]
+ git = '{}'
+ "#, bar.url()))
+ .file("src/main.rs", "fn main() {}");
+ assert_that(p.cargo_process("fetch"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] git repository `{url}`
+", url = bar.url())));
+
+ assert_that(p.cargo("fetch"),
+ execs().with_status(0).with_stdout(""));
+}
+
+#[test]
+fn warnings_in_git_dep() {
+ let bar = git::new("bar", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", "fn unused() {}")
+ }).unwrap();
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ [dependencies.bar]
+ git = '{}'
+ "#, bar.url()))
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("build"),
+ execs()
+ .with_stderr(&format!("[UPDATING] git repository `{}`\n\
+ [COMPILING] bar v0.5.0 ({}#[..])\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ bar.url(),
+ bar.url(),
+ p.url())));
+}
+
+#[test]
+fn update_ambiguous() {
+ let foo1 = git::new("foo1", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", "")
+ }).unwrap();
+ let foo2 = git::new("foo2", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.6.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", "")
+ }).unwrap();
+ let bar = git::new("bar", |project| {
+ project.file("Cargo.toml", &format!(r#"
+ [package]
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.foo]
+ git = '{}'
+ "#, foo2.url()))
+ .file("src/lib.rs", "")
+ }).unwrap();
+
+ let p = project("project")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "project"
+ version = "0.5.0"
+ authors = []
+ [dependencies.foo]
+ git = '{}'
+ [dependencies.bar]
+ git = '{}'
+ "#, foo1.url(), bar.url()))
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("generate-lockfile"), execs().with_status(0));
+ assert_that(p.cargo("update")
+ .arg("-p").arg("foo"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] There are multiple `foo` packages in your project, and the specification `foo` \
+is ambiguous.
+Please re-run this command with `-p <spec>` where `<spec>` is one of the \
+following:
+ foo:0.[..].0
+ foo:0.[..].0
+"));
+}
+
+#[test]
+fn update_one_dep_in_repo_with_many_deps() {
+ let foo = git::new("foo", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("a/src/lib.rs", "")
+ }).unwrap();
+
+ let p = project("project")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "project"
+ version = "0.5.0"
+ authors = []
+ [dependencies.foo]
+ git = '{}'
+ [dependencies.a]
+ git = '{}'
+ "#, foo.url(), foo.url()))
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("generate-lockfile"), execs().with_status(0));
+ assert_that(p.cargo("update")
+ .arg("-p").arg("foo"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[UPDATING] git repository `{}`
+", foo.url())));
+}
+
+#[test]
+fn switch_deps_does_not_update_transitive() {
+ let transitive = git::new("transitive", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "transitive"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", "")
+ }).unwrap();
+ let dep1 = git::new("dep1", |project| {
+ project.file("Cargo.toml", &format!(r#"
+ [package]
+ name = "dep"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.transitive]
+ git = '{}'
+ "#, transitive.url()))
+ .file("src/lib.rs", "")
+ }).unwrap();
+ let dep2 = git::new("dep2", |project| {
+ project.file("Cargo.toml", &format!(r#"
+ [package]
+ name = "dep"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.transitive]
+ git = '{}'
+ "#, transitive.url()))
+ .file("src/lib.rs", "")
+ }).unwrap();
+
+ let p = project("project")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "project"
+ version = "0.5.0"
+ authors = []
+ [dependencies.dep]
+ git = '{}'
+ "#, dep1.url()))
+ .file("src/main.rs", "fn main() {}");
+
+ p.build();
+ assert_that(p.cargo("build"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[UPDATING] git repository `{}`
+[UPDATING] git repository `{}`
+[COMPILING] transitive [..]
+[COMPILING] dep [..]
+[COMPILING] project [..]
+", dep1.url(), transitive.url())));
+
+ // Update the dependency to point to the second repository, but this
+ // shouldn't update the transitive dependency which is the same.
+ File::create(&p.root().join("Cargo.toml")).unwrap().write_all(format!(r#"
+ [project]
+ name = "project"
+ version = "0.5.0"
+ authors = []
+ [dependencies.dep]
+ git = '{}'
+ "#, dep2.url()).as_bytes()).unwrap();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[UPDATING] git repository `{}`
+[COMPILING] dep [..]
+[COMPILING] project [..]
+", dep2.url())));
+}
+
+#[test]
+fn update_one_source_updates_all_packages_in_that_git_source() {
+ let dep = git::new("dep", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "dep"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies.a]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "")
+ }).unwrap();
+
+ let p = project("project")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "project"
+ version = "0.5.0"
+ authors = []
+ [dependencies.dep]
+ git = '{}'
+ "#, dep.url()))
+ .file("src/main.rs", "fn main() {}");
+
+ p.build();
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+
+ let repo = git2::Repository::open(&dep.root()).unwrap();
+ let rev1 = repo.revparse_single("HEAD").unwrap().id();
+
+ // Just be sure to change a file
+ File::create(&dep.root().join("src/lib.rs")).unwrap().write_all(br#"
+ pub fn bar() -> i32 { 2 }
+ "#).unwrap();
+ git::add(&repo);
+ git::commit(&repo);
+
+ assert_that(p.cargo("update").arg("-p").arg("dep"),
+ execs().with_status(0));
+ let mut lockfile = String::new();
+ File::open(&p.root().join("Cargo.lock")).unwrap()
+ .read_to_string(&mut lockfile).unwrap();
+ assert!(!lockfile.contains(&rev1.to_string()),
+ "{} in {}", rev1, lockfile);
+}
+
+#[test]
+fn switch_sources() {
+ let a1 = git::new("a1", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ }).unwrap();
+ let a2 = git::new("a2", |project| {
+ project.file("Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.5.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ }).unwrap();
+
+ let p = project("project")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "project"
+ version = "0.5.0"
+ authors = []
+ [dependencies.b]
+ path = "b"
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("b/Cargo.toml", &format!(r#"
+ [project]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+ [dependencies.a]
+ git = '{}'
+ "#, a1.url()))
+ .file("b/src/lib.rs", "pub fn main() {}");
+
+ p.build();
+ assert_that(p.cargo("build"),
+ execs().with_status(0)
+ .with_stderr("\
+[UPDATING] git repository `file://[..]a1`
+[COMPILING] a v0.5.0 ([..]a1#[..]
+[COMPILING] b v0.5.0 ([..])
+[COMPILING] project v0.5.0 ([..])
+"));
+
+ File::create(&p.root().join("b/Cargo.toml")).unwrap().write_all(format!(r#"
+ [project]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+ [dependencies.a]
+ git = '{}'
+ "#, a2.url()).as_bytes()).unwrap();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0)
+ .with_stderr("\
+[UPDATING] git repository `file://[..]a2`
+[COMPILING] a v0.5.1 ([..]a2#[..]
+[COMPILING] b v0.5.0 ([..])
+[COMPILING] project v0.5.0 ([..])
+"));
+}
+
+#[test]
+fn dont_require_submodules_are_checked_out() {
+ let project = project("foo");
+ let git1 = git::new("dep1", |p| {
+ p.file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("build.rs", "fn main() {}")
+ .file("src/lib.rs", "")
+ .file("a/foo", "")
+ }).unwrap();
+ let git2 = git::new("dep2", |p| p).unwrap();
+
+ let repo = git2::Repository::open(&git1.root()).unwrap();
+ let url = path2url(git2.root()).to_string();
+ git::add_submodule(&repo, &url, &Path::new("a/submodule"));
+ git::commit(&repo);
+
+ git2::Repository::init(&project.root()).unwrap();
+ let url = path2url(git1.root()).to_string();
+ let dst = paths::home().join("foo");
+ git2::Repository::clone(&url, &dst).unwrap();
+
+ assert_that(git1.cargo("build").arg("-v").cwd(&dst),
+ execs().with_status(0));
+}
+
+#[test]
+fn doctest_same_name() {
+ let a2 = git::new("a2", |p| {
+ p.file("Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn a2() {}")
+ }).unwrap();
+
+ let a1 = git::new("a1", |p| {
+ p.file("Cargo.toml", &format!(r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ [dependencies]
+ a = {{ git = '{}' }}
+ "#, a2.url()))
+ .file("src/lib.rs", "extern crate a; pub fn a1() {}")
+ }).unwrap();
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ a = {{ git = '{}' }}
+ "#, a1.url()))
+ .file("src/lib.rs", r#"
+ #[macro_use]
+ extern crate a;
+ "#);
+
+ assert_that(p.cargo_process("test").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn lints_are_suppressed() {
+ let a = git::new("a", |p| {
+ p.file("Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "
+ use std::option;
+ ")
+ }).unwrap();
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ a = {{ git = '{}' }}
+ "#, a.url()))
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] git repository `[..]`
+[COMPILING] a v0.5.0 ([..])
+[COMPILING] foo v0.0.1 ([..])
+"));
+}
+
+#[test]
+fn denied_lints_are_allowed() {
+ let enabled = RUSTC.with(|r| r.cap_lints);
+ if !enabled { return }
+
+ let a = git::new("a", |p| {
+ p.file("Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "
+ #![deny(warnings)]
+ use std::option;
+ ")
+ }).unwrap();
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ a = {{ git = '{}' }}
+ "#, a.url()))
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] git repository `[..]`
+[COMPILING] a v0.5.0 ([..])
+[COMPILING] foo v0.0.1 ([..])
+"));
+}
+
+#[test]
+fn add_a_git_dep() {
+ let git = git::new("git", |p| {
+ p.file("Cargo.toml", r#"
+ [project]
+ name = "git"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ }).unwrap();
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ a = {{ path = 'a' }}
+ git = {{ git = '{}' }}
+ "#, git.url()))
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+
+ File::create(p.root().join("a/Cargo.toml")).unwrap().write_all(format!(r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ git = {{ git = '{}' }}
+ "#, git.url()).as_bytes()).unwrap();
+
+ assert_that(p.cargo("build"), execs().with_status(0));
+}
--- /dev/null
+extern crate cargotest;
+extern crate cargo;
+extern crate tempdir;
+extern crate hamcrest;
+
+use std::fs::{self, File};
+use std::io::prelude::*;
+use std::env;
+
+use cargo::util::{process, ProcessBuilder};
+use cargotest::support::{execs, paths, cargo_dir};
+use hamcrest::{assert_that, existing_file, existing_dir, is_not};
+use tempdir::TempDir;
+
+fn cargo_process(s: &str) -> ProcessBuilder {
+ let mut p = process(&cargo_dir().join("cargo"));
+ p.arg(s).cwd(&paths::root()).env("HOME", &paths::home());
+ return p;
+}
+
+#[test]
+fn simple_lib() {
+ assert_that(cargo_process("init").arg("--vcs").arg("none")
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+ assert_that(&paths::root().join("Cargo.toml"), existing_file());
+ assert_that(&paths::root().join("src/lib.rs"), existing_file());
+ assert_that(&paths::root().join(".gitignore"), is_not(existing_file()));
+
+ assert_that(cargo_process("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn simple_bin() {
+ let path = paths::root().join("foo");
+ fs::create_dir(&path).unwrap();
+ assert_that(cargo_process("init").arg("--bin").arg("--vcs").arg("none")
+ .env("USER", "foo").cwd(&path),
+ execs().with_status(0));
+
+ assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
+ assert_that(&paths::root().join("foo/src/main.rs"), existing_file());
+
+ assert_that(cargo_process("build").cwd(&path),
+ execs().with_status(0));
+ assert_that(&paths::root().join(&format!("foo/target/debug/foo{}",
+ env::consts::EXE_SUFFIX)),
+ existing_file());
+}
+
+fn bin_already_exists(explicit: bool, rellocation: &str) {
+ let path = paths::root().join("foo");
+ fs::create_dir_all(&path.join("src")).unwrap();
+
+ let sourcefile_path = path.join(rellocation);
+
+ let content = br#"
+ fn main() {
+ println!("Hello, world 2!");
+ }
+ "#;
+
+ File::create(&sourcefile_path).unwrap().write_all(content).unwrap();
+
+ if explicit {
+ assert_that(cargo_process("init").arg("--bin").arg("--vcs").arg("none")
+ .env("USER", "foo").cwd(&path),
+ execs().with_status(0));
+ } else {
+ assert_that(cargo_process("init").arg("--vcs").arg("none")
+ .env("USER", "foo").cwd(&path),
+ execs().with_status(0));
+ }
+
+ assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
+ assert_that(&paths::root().join("foo/src/lib.rs"), is_not(existing_file()));
+
+ // Check that our file is not overwritten
+ let mut new_content = Vec::new();
+ File::open(&sourcefile_path).unwrap().read_to_end(&mut new_content).unwrap();
+ assert_eq!(Vec::from(content as &[u8]), new_content);
+}
+
+#[test]
+fn bin_already_exists_explicit() {
+ bin_already_exists(true, "src/main.rs")
+}
+
+#[test]
+fn bin_already_exists_implicit() {
+ bin_already_exists(false, "src/main.rs")
+}
+
+#[test]
+fn bin_already_exists_explicit_nosrc() {
+ bin_already_exists(true, "main.rs")
+}
+
+#[test]
+fn bin_already_exists_implicit_nosrc() {
+ bin_already_exists(false, "main.rs")
+}
+
+#[test]
+fn bin_already_exists_implicit_namenosrc() {
+ bin_already_exists(false, "foo.rs")
+}
+
+#[test]
+fn bin_already_exists_implicit_namesrc() {
+ bin_already_exists(false, "src/foo.rs")
+}
+
+#[test]
+fn confused_by_multiple_lib_files() {
+ let path = paths::root().join("foo");
+ fs::create_dir_all(&path.join("src")).unwrap();
+
+ let sourcefile_path1 = path.join("src/lib.rs");
+
+ File::create(&sourcefile_path1).unwrap().write_all(br#"
+ fn qqq () {
+ println!("Hello, world 2!");
+ }
+ "#).unwrap();
+
+ let sourcefile_path2 = path.join("lib.rs");
+
+ File::create(&sourcefile_path2).unwrap().write_all(br#"
+ fn qqq () {
+ println!("Hello, world 3!");
+ }
+ "#).unwrap();
+
+ assert_that(cargo_process("init").arg("--vcs").arg("none")
+ .env("USER", "foo").cwd(&path),
+ execs().with_status(101).with_stderr("\
+[ERROR] cannot have a project with multiple libraries, found both `src/lib.rs` and `lib.rs`
+"));
+
+ assert_that(&paths::root().join("foo/Cargo.toml"), is_not(existing_file()));
+}
+
+
+#[test]
+fn multibin_project_name_clash() {
+ let path = paths::root().join("foo");
+ fs::create_dir(&path).unwrap();
+
+ let sourcefile_path1 = path.join("foo.rs");
+
+ File::create(&sourcefile_path1).unwrap().write_all(br#"
+ fn main () {
+ println!("Hello, world 2!");
+ }
+ "#).unwrap();
+
+ let sourcefile_path2 = path.join("main.rs");
+
+ File::create(&sourcefile_path2).unwrap().write_all(br#"
+ fn main () {
+ println!("Hello, world 3!");
+ }
+ "#).unwrap();
+
+ assert_that(cargo_process("init").arg("--vcs").arg("none")
+ .env("USER", "foo").cwd(&path),
+ execs().with_status(101).with_stderr("\
+[ERROR] multiple possible binary sources found:
+ main.rs
+ foo.rs
+cannot automatically generate Cargo.toml as the main target would be ambiguous
+"));
+
+ assert_that(&paths::root().join("foo/Cargo.toml"), is_not(existing_file()));
+}
+
+fn lib_already_exists(rellocation: &str) {
+ let path = paths::root().join("foo");
+ fs::create_dir_all(&path.join("src")).unwrap();
+
+ let sourcefile_path = path.join(rellocation);
+
+ let content = br#"
+ pub fn qqq() {}
+ "#;
+
+ File::create(&sourcefile_path).unwrap().write_all(content).unwrap();
+
+ assert_that(cargo_process("init").arg("--vcs").arg("none")
+ .env("USER", "foo").cwd(&path),
+ execs().with_status(0));
+
+ assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
+ assert_that(&paths::root().join("foo/src/main.rs"), is_not(existing_file()));
+
+ // Check that our file is not overwritten
+ let mut new_content = Vec::new();
+ File::open(&sourcefile_path).unwrap().read_to_end(&mut new_content).unwrap();
+ assert_eq!(Vec::from(content as &[u8]), new_content);
+}
+
+#[test]
+fn lib_already_exists_src() {
+ lib_already_exists("src/lib.rs")
+}
+
+#[test]
+fn lib_already_exists_nosrc() {
+ lib_already_exists("lib.rs")
+}
+
+#[test]
+fn simple_git() {
+ assert_that(cargo_process("init").arg("--vcs").arg("git")
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+ assert_that(&paths::root().join("Cargo.toml"), existing_file());
+ assert_that(&paths::root().join("src/lib.rs"), existing_file());
+ assert_that(&paths::root().join(".git"), existing_dir());
+ assert_that(&paths::root().join(".gitignore"), existing_file());
+}
+
+#[test]
+fn auto_git() {
+ let td = TempDir::new("cargo").unwrap();
+ let foo = &td.path().join("foo");
+ fs::create_dir_all(&foo).unwrap();
+ assert_that(cargo_process("init").cwd(foo.clone())
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+ assert_that(&foo.join("Cargo.toml"), existing_file());
+ assert_that(&foo.join("src/lib.rs"), existing_file());
+ assert_that(&foo.join(".git"), existing_dir());
+ assert_that(&foo.join(".gitignore"), existing_file());
+}
+
+#[test]
+fn invalid_dir_name() {
+ let foo = &paths::root().join("foo.bar");
+ fs::create_dir_all(&foo).unwrap();
+ assert_that(cargo_process("init").cwd(foo.clone())
+ .env("USER", "foo"),
+ execs().with_status(101).with_stderr("\
+[ERROR] Invalid character `.` in crate name: `foo.bar`
+use --name to override crate name
+"));
+
+ assert_that(&foo.join("Cargo.toml"), is_not(existing_file()));
+}
+
+#[test]
+fn reserved_name() {
+ let test = &paths::root().join("test");
+ fs::create_dir_all(&test).unwrap();
+ assert_that(cargo_process("init").cwd(test.clone())
+ .env("USER", "foo"),
+ execs().with_status(101).with_stderr("\
+[ERROR] The name `test` cannot be used as a crate name\n\
+use --name to override crate name
+"));
+
+ assert_that(&test.join("Cargo.toml"), is_not(existing_file()));
+}
+
+#[test]
+fn git_autodetect() {
+ fs::create_dir(&paths::root().join(".git")).unwrap();
+
+ assert_that(cargo_process("init")
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+
+ assert_that(&paths::root().join("Cargo.toml"), existing_file());
+ assert_that(&paths::root().join("src/lib.rs"), existing_file());
+ assert_that(&paths::root().join(".git"), existing_dir());
+ assert_that(&paths::root().join(".gitignore"), existing_file());
+}
+
+
+#[test]
+fn mercurial_autodetect() {
+ fs::create_dir(&paths::root().join(".hg")).unwrap();
+
+ assert_that(cargo_process("init")
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+
+ assert_that(&paths::root().join("Cargo.toml"), existing_file());
+ assert_that(&paths::root().join("src/lib.rs"), existing_file());
+ assert_that(&paths::root().join(".git"), is_not(existing_dir()));
+ assert_that(&paths::root().join(".hgignore"), existing_file());
+}
+
+#[test]
+fn gitignore_appended_not_replaced() {
+ fs::create_dir(&paths::root().join(".git")).unwrap();
+
+ File::create(&paths::root().join(".gitignore")).unwrap().write_all(b"qqqqqq\n").unwrap();
+
+ assert_that(cargo_process("init")
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+
+ assert_that(&paths::root().join("Cargo.toml"), existing_file());
+ assert_that(&paths::root().join("src/lib.rs"), existing_file());
+ assert_that(&paths::root().join(".git"), existing_dir());
+ assert_that(&paths::root().join(".gitignore"), existing_file());
+
+ let mut contents = String::new();
+ File::open(&paths::root().join(".gitignore")).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"qqqqqq"#));
+}
+
+#[test]
+fn cargo_lock_gitignored_if_lib1() {
+ fs::create_dir(&paths::root().join(".git")).unwrap();
+
+ assert_that(cargo_process("init").arg("--vcs").arg("git")
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+ assert_that(&paths::root().join(".gitignore"), existing_file());
+
+ let mut contents = String::new();
+ File::open(&paths::root().join(".gitignore")).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"Cargo.lock"#));
+}
+
+#[test]
+fn cargo_lock_gitignored_if_lib2() {
+ fs::create_dir(&paths::root().join(".git")).unwrap();
+
+ File::create(&paths::root().join("lib.rs")).unwrap().write_all(br#""#).unwrap();
+
+ assert_that(cargo_process("init").arg("--vcs").arg("git")
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+ assert_that(&paths::root().join(".gitignore"), existing_file());
+
+ let mut contents = String::new();
+ File::open(&paths::root().join(".gitignore")).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"Cargo.lock"#));
+}
+
+#[test]
+fn cargo_lock_not_gitignored_if_bin1() {
+ fs::create_dir(&paths::root().join(".git")).unwrap();
+
+ assert_that(cargo_process("init").arg("--vcs").arg("git")
+ .arg("--bin")
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+ assert_that(&paths::root().join(".gitignore"), existing_file());
+
+ let mut contents = String::new();
+ File::open(&paths::root().join(".gitignore")).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(!contents.contains(r#"Cargo.lock"#));
+}
+
+#[test]
+fn cargo_lock_not_gitignored_if_bin2() {
+ fs::create_dir(&paths::root().join(".git")).unwrap();
+
+ File::create(&paths::root().join("main.rs")).unwrap().write_all(br#""#).unwrap();
+
+ assert_that(cargo_process("init").arg("--vcs").arg("git")
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+ assert_that(&paths::root().join(".gitignore"), existing_file());
+
+ let mut contents = String::new();
+ File::open(&paths::root().join(".gitignore")).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(!contents.contains(r#"Cargo.lock"#));
+}
+
+#[test]
+fn with_argument() {
+ assert_that(cargo_process("init").arg("foo").arg("--vcs").arg("none")
+ .env("USER", "foo"),
+ execs().with_status(0));
+ assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
+}
+
+
+#[test]
+fn unknown_flags() {
+ assert_that(cargo_process("init").arg("foo").arg("--flag"),
+ execs().with_status(1)
+ .with_stderr("\
+[ERROR] Unknown flag: '--flag'
+
+Usage:
+ cargo init [options] [<path>]
+ cargo init -h | --help
+"));
+}
+
+#[cfg(not(windows))]
+#[test]
+fn no_filename() {
+ assert_that(cargo_process("init").arg("/"),
+ execs().with_status(101)
+ .with_stderr(&format!("\
+[ERROR] cannot auto-detect project name from path \"/\" ; use --name to override
+")));
+}
--- /dev/null
+extern crate cargo;
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::fs::{self, File};
+use std::io::prelude::*;
+
+use cargo::util::ProcessBuilder;
+use cargotest::install::{cargo_home, has_installed_exe};
+use cargotest::support::git;
+use cargotest::support::paths;
+use cargotest::support::registry::Package;
+use cargotest::support::{project, execs};
+use hamcrest::{assert_that, is_not};
+
+fn cargo_process(s: &str) -> ProcessBuilder {
+ let mut p = cargotest::cargo_process();
+ p.arg(s);
+ return p
+}
+
+fn pkg(name: &str, vers: &str) {
+ Package::new(name, vers)
+ .file("src/lib.rs", "")
+ .file("src/main.rs", &format!("
+ extern crate {};
+ fn main() {{}}
+ ", name))
+ .publish()
+}
+
+#[test]
+fn simple() {
+ pkg("foo", "0.0.1");
+
+ assert_that(cargo_process("install").arg("foo"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] registry `[..]`
+[DOWNLOADING] foo v0.0.1 (registry file://[..])
+[COMPILING] foo v0.0.1 (registry file://[..])
+[INSTALLING] {home}[..]bin[..]foo[..]
+warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
+",
+ home = cargo_home().display())));
+ assert_that(cargo_home(), has_installed_exe("foo"));
+
+ assert_that(cargo_process("uninstall").arg("foo"),
+ execs().with_status(0).with_stderr(&format!("\
+[REMOVING] {home}[..]bin[..]foo[..]
+",
+ home = cargo_home().display())));
+ assert_that(cargo_home(), is_not(has_installed_exe("foo")));
+}
+
+#[test]
+fn pick_max_version() {
+ pkg("foo", "0.0.1");
+ pkg("foo", "0.0.2");
+
+ assert_that(cargo_process("install").arg("foo"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] registry `[..]`
+[DOWNLOADING] foo v0.0.2 (registry file://[..])
+[COMPILING] foo v0.0.2 (registry file://[..])
+[INSTALLING] {home}[..]bin[..]foo[..]
+warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
+",
+ home = cargo_home().display())));
+ assert_that(cargo_home(), has_installed_exe("foo"));
+}
+
+#[test]
+fn missing() {
+ pkg("foo", "0.0.1");
+ assert_that(cargo_process("install").arg("bar"),
+ execs().with_status(101).with_stderr("\
+[UPDATING] registry [..]
+[ERROR] could not find `bar` in `registry file://[..]`
+"));
+}
+
+#[test]
+fn bad_version() {
+ pkg("foo", "0.0.1");
+ assert_that(cargo_process("install").arg("foo").arg("--vers=0.2.0"),
+ execs().with_status(101).with_stderr("\
+[UPDATING] registry [..]
+[ERROR] could not find `foo` in `registry file://[..]` with version `0.2.0`
+"));
+}
+
+#[test]
+fn no_crate() {
+ assert_that(cargo_process("install"),
+ execs().with_status(101).with_stderr("\
+[ERROR] `[..]` is not a crate root; specify a crate to install [..]
+
+Caused by:
+ failed to read `[..]Cargo.toml`
+
+Caused by:
+ [..] (os error [..])
+"));
+}
+
+#[test]
+fn install_location_precedence() {
+ pkg("foo", "0.0.1");
+
+ let root = paths::root();
+ let t1 = root.join("t1");
+ let t2 = root.join("t2");
+ let t3 = root.join("t3");
+ let t4 = cargo_home();
+
+ fs::create_dir(root.join(".cargo")).unwrap();
+ File::create(root.join(".cargo/config")).unwrap().write_all(format!("\
+ [install]
+ root = '{}'
+ ", t3.display()).as_bytes()).unwrap();
+
+ println!("install --root");
+
+ assert_that(cargo_process("install").arg("foo")
+ .arg("--root").arg(&t1)
+ .env("CARGO_INSTALL_ROOT", &t2),
+ execs().with_status(0));
+ assert_that(&t1, has_installed_exe("foo"));
+ assert_that(&t2, is_not(has_installed_exe("foo")));
+
+ println!("install CARGO_INSTALL_ROOT");
+
+ assert_that(cargo_process("install").arg("foo")
+ .env("CARGO_INSTALL_ROOT", &t2),
+ execs().with_status(0));
+ assert_that(&t2, has_installed_exe("foo"));
+ assert_that(&t3, is_not(has_installed_exe("foo")));
+
+ println!("install install.root");
+
+ assert_that(cargo_process("install").arg("foo"),
+ execs().with_status(0));
+ assert_that(&t3, has_installed_exe("foo"));
+ assert_that(&t4, is_not(has_installed_exe("foo")));
+
+ fs::remove_file(root.join(".cargo/config")).unwrap();
+
+ println!("install cargo home");
+
+ assert_that(cargo_process("install").arg("foo"),
+ execs().with_status(0));
+ assert_that(&t4, has_installed_exe("foo"));
+}
+
+#[test]
+fn install_path() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--path").arg(p.root()),
+ execs().with_status(0));
+ assert_that(cargo_home(), has_installed_exe("foo"));
+ assert_that(cargo_process("install").arg("--path").arg(".").cwd(p.root()),
+ execs().with_status(101).with_stderr("\
+[ERROR] binary `foo[..]` already exists in destination as part of `foo v0.1.0 [..]`
+Add --force to overwrite
+"));
+}
+
+#[test]
+fn multiple_crates_error() {
+ let p = git::repo(&paths::root().join("foo"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("a/src/main.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--git").arg(p.url().to_string()),
+ execs().with_status(101).with_stderr("\
+[UPDATING] git repository [..]
+[ERROR] multiple packages with binaries found: bar, foo
+"));
+}
+
+#[test]
+fn multiple_crates_select() {
+ let p = git::repo(&paths::root().join("foo"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("a/src/main.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--git").arg(p.url().to_string())
+ .arg("foo"),
+ execs().with_status(0));
+ assert_that(cargo_home(), has_installed_exe("foo"));
+ assert_that(cargo_home(), is_not(has_installed_exe("bar")));
+
+ assert_that(cargo_process("install").arg("--git").arg(p.url().to_string())
+ .arg("bar"),
+ execs().with_status(0));
+ assert_that(cargo_home(), has_installed_exe("bar"));
+}
+
+#[test]
+fn multiple_crates_auto_binaries() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ bar = { path = "a" }
+ "#)
+ .file("src/main.rs", "extern crate bar; fn main() {}")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--path").arg(p.root()),
+ execs().with_status(0));
+ assert_that(cargo_home(), has_installed_exe("foo"));
+}
+
+#[test]
+fn multiple_crates_auto_examples() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ bar = { path = "a" }
+ "#)
+ .file("src/lib.rs", "extern crate bar;")
+ .file("examples/foo.rs", "
+ extern crate bar;
+ extern crate foo;
+ fn main() {}
+ ")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--path").arg(p.root())
+ .arg("--example=foo"),
+ execs().with_status(0));
+ assert_that(cargo_home(), has_installed_exe("foo"));
+}
+
+#[test]
+fn no_binaries_or_examples() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ bar = { path = "a" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--path").arg(p.root()),
+ execs().with_status(101).with_stderr("\
+[ERROR] no packages found with binaries or examples
+"));
+}
+
+#[test]
+fn no_binaries() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("examples/foo.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--path").arg(p.root()).arg("foo"),
+ execs().with_status(101).with_stderr("\
+[ERROR] specified package has no binaries
+"));
+}
+
+#[test]
+fn examples() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("examples/foo.rs", "extern crate foo; fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--path").arg(p.root())
+ .arg("--example=foo"),
+ execs().with_status(0));
+ assert_that(cargo_home(), has_installed_exe("foo"));
+}
+
+#[test]
+fn install_twice() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/bin/foo-bin1.rs", "fn main() {}")
+ .file("src/bin/foo-bin2.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--path").arg(p.root()),
+ execs().with_status(0));
+ assert_that(cargo_process("install").arg("--path").arg(p.root()),
+ execs().with_status(101).with_stderr("\
+[ERROR] binary `foo-bin1[..]` already exists in destination as part of `foo v0.1.0 ([..])`
+binary `foo-bin2[..]` already exists in destination as part of `foo v0.1.0 ([..])`
+Add --force to overwrite
+"));
+}
+
+#[test]
+fn install_force() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--path").arg(p.root()),
+ execs().with_status(0));
+
+ let p = project("foo2")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.2.0"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--force").arg("--path").arg(p.root()),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] foo v0.2.0 ([..])
+[REPLACING] {home}[..]bin[..]foo[..]
+warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
+",
+ home = cargo_home().display())));
+
+ assert_that(cargo_process("install").arg("--list"),
+ execs().with_status(0).with_stdout("\
+foo v0.2.0 ([..]):
+ foo[..]
+"));
+}
+
+#[test]
+fn install_force_partial_overlap() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/bin/foo-bin1.rs", "fn main() {}")
+ .file("src/bin/foo-bin2.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--path").arg(p.root()),
+ execs().with_status(0));
+
+ let p = project("foo2")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.2.0"
+ authors = []
+ "#)
+ .file("src/bin/foo-bin2.rs", "fn main() {}")
+ .file("src/bin/foo-bin3.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--force").arg("--path").arg(p.root()),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] foo v0.2.0 ([..])
+[INSTALLING] {home}[..]bin[..]foo-bin3[..]
+[REPLACING] {home}[..]bin[..]foo-bin2[..]
+warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
+",
+ home = cargo_home().display())));
+
+ assert_that(cargo_process("install").arg("--list"),
+ execs().with_status(0).with_stdout("\
+foo v0.1.0 ([..]):
+ foo-bin1[..]
+foo v0.2.0 ([..]):
+ foo-bin2[..]
+ foo-bin3[..]
+"));
+}
+
+#[test]
+fn install_force_bin() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/bin/foo-bin1.rs", "fn main() {}")
+ .file("src/bin/foo-bin2.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--path").arg(p.root()),
+ execs().with_status(0));
+
+ let p = project("foo2")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.2.0"
+ authors = []
+ "#)
+ .file("src/bin/foo-bin1.rs", "fn main() {}")
+ .file("src/bin/foo-bin2.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--force")
+ .arg("--bin")
+ .arg("foo-bin2")
+ .arg("--path")
+ .arg(p.root()),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] foo v0.2.0 ([..])
+[REPLACING] {home}[..]bin[..]foo-bin2[..]
+warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
+",
+ home = cargo_home().display())));
+
+ assert_that(cargo_process("install").arg("--list"),
+ execs().with_status(0).with_stdout("\
+foo v0.1.0 ([..]):
+ foo-bin1[..]
+foo v0.2.0 ([..]):
+ foo-bin2[..]
+"));
+}
+
+#[test]
+fn compile_failure() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/main.rs", "");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--path").arg(p.root()),
+ execs().with_status(101).with_stderr("\
+[COMPILING] foo v0.1.0 [..]
+error: main function not found
+error: aborting due to previous error
+[ERROR] failed to compile `foo v0.1.0 (file://[..])`, intermediate artifacts can be \
+ found at `[..]target`
+
+Caused by:
+ Could not compile `foo`.
+
+To learn more, run the command again with --verbose.
+"));
+}
+
+#[test]
+fn git_repo() {
+ let p = git::repo(&paths::root().join("foo"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--git").arg(p.url().to_string()),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] git repository `[..]`
+[COMPILING] foo v0.1.0 ([..])
+[INSTALLING] {home}[..]bin[..]foo[..]
+warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
+",
+ home = cargo_home().display())));
+ assert_that(cargo_home(), has_installed_exe("foo"));
+ assert_that(cargo_home(), has_installed_exe("foo"));
+}
+
+#[test]
+fn list() {
+ pkg("foo", "0.0.1");
+ pkg("bar", "0.2.1");
+ pkg("bar", "0.2.2");
+
+ assert_that(cargo_process("install").arg("--list"),
+ execs().with_status(0).with_stdout(""));
+
+ assert_that(cargo_process("install").arg("bar").arg("--vers").arg("=0.2.1"),
+ execs().with_status(0));
+ assert_that(cargo_process("install").arg("foo"),
+ execs().with_status(0));
+ assert_that(cargo_process("install").arg("--list"),
+ execs().with_status(0).with_stdout("\
+bar v0.2.1 (registry [..]):
+ bar[..]
+foo v0.0.1 (registry [..]):
+ foo[..]
+"));
+}
+
+#[test]
+fn uninstall_pkg_does_not_exist() {
+ assert_that(cargo_process("uninstall").arg("foo"),
+ execs().with_status(101).with_stderr("\
+[ERROR] package id specification `foo` matched no packages
+"));
+}
+
+#[test]
+fn uninstall_bin_does_not_exist() {
+ pkg("foo", "0.0.1");
+
+ assert_that(cargo_process("install").arg("foo"),
+ execs().with_status(0));
+ assert_that(cargo_process("uninstall").arg("foo").arg("--bin=bar"),
+ execs().with_status(101).with_stderr("\
+[ERROR] binary `bar[..]` not installed as part of `foo v0.0.1 ([..])`
+"));
+}
+
+#[test]
+fn uninstall_piecemeal() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/bin/foo.rs", "fn main() {}")
+ .file("src/bin/bar.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("--path").arg(p.root()),
+ execs().with_status(0));
+ assert_that(cargo_home(), has_installed_exe("foo"));
+ assert_that(cargo_home(), has_installed_exe("bar"));
+
+ assert_that(cargo_process("uninstall").arg("foo").arg("--bin=bar"),
+ execs().with_status(0).with_stderr("\
+[REMOVING] [..]bar[..]
+"));
+
+ assert_that(cargo_home(), has_installed_exe("foo"));
+ assert_that(cargo_home(), is_not(has_installed_exe("bar")));
+
+ assert_that(cargo_process("uninstall").arg("foo").arg("--bin=foo"),
+ execs().with_status(0).with_stderr("\
+[REMOVING] [..]foo[..]
+"));
+ assert_that(cargo_home(), is_not(has_installed_exe("foo")));
+
+ assert_that(cargo_process("uninstall").arg("foo"),
+ execs().with_status(101).with_stderr("\
+[ERROR] package id specification `foo` matched no packages
+"));
+}
+
+#[test]
+fn subcommand_works_out_of_the_box() {
+ Package::new("cargo-foo", "1.0.0")
+ .file("src/main.rs", r#"
+ fn main() {
+ println!("bar");
+ }
+ "#)
+ .publish();
+ assert_that(cargo_process("install").arg("cargo-foo"),
+ execs().with_status(0));
+ assert_that(cargo_process("foo"),
+ execs().with_status(0).with_stdout("bar\n"));
+ assert_that(cargo_process("--list"),
+ execs().with_status(0).with_stdout_contains(" foo\n"));
+}
+
+#[test]
+fn installs_from_cwd_by_default() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").cwd(p.root()),
+ execs().with_status(0));
+ assert_that(cargo_home(), has_installed_exe("foo"));
+}
+
+#[test]
+fn do_not_rebuilds_on_local_install() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("build").arg("--release"),
+ execs().with_status(0));
+ assert_that(cargo_process("install").arg("--path").arg(p.root()),
+ execs().with_status(0).with_stderr("\
+[INSTALLING] [..]
+warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
+"));
+
+ assert!(p.build_dir().exists());
+ assert!(p.release_bin("foo").exists());
+ assert_that(cargo_home(), has_installed_exe("foo"));
+}
+
+#[test]
+fn reports_unsuccessful_subcommand_result() {
+ Package::new("cargo-fail", "1.0.0")
+ .file("src/main.rs", r#"
+ fn main() {
+ panic!();
+ }
+ "#)
+ .publish();
+ assert_that(cargo_process("install").arg("cargo-fail"),
+ execs().with_status(0));
+ assert_that(cargo_process("--list"),
+ execs().with_status(0).with_stdout_contains(" fail\n"));
+ assert_that(cargo_process("fail"),
+ execs().with_status(101).with_stderr_contains("\
+thread '<main>' panicked at 'explicit panic', [..]
+"));
+}
+
+#[test]
+fn git_with_lockfile() {
+ let p = git::repo(&paths::root().join("foo"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ bar = { path = "bar" }
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "fn main() {}")
+ .file("Cargo.lock", r#"
+ [root]
+ name = "foo"
+ version = "0.1.0"
+ dependencies = [ "b 0.1.0" ]
+
+ [[package]]
+ name = "bar"
+ version = "0.1.0"
+ "#);
+ p.build();
+
+ assert_that(cargo_process("install").arg("--git").arg(p.url().to_string()),
+ execs().with_status(0));
+}
+
+#[test]
+fn q_silences_warnings() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ assert_that(cargo_process("install").arg("-q").arg("--path").arg(p.root()),
+ execs().with_status(0).with_stderr(""));
+}
+
+#[test]
+fn readonly_dir() {
+ pkg("foo", "0.0.1");
+
+ let root = paths::root();
+ let dir = &root.join("readonly");
+ fs::create_dir(root.join("readonly")).unwrap();
+ let mut perms = fs::metadata(dir).unwrap().permissions();
+ perms.set_readonly(true);
+ fs::set_permissions(dir, perms).unwrap();
+
+ assert_that(cargo_process("install").arg("foo").cwd(dir),
+ execs().with_status(0));
+ assert_that(cargo_home(), has_installed_exe("foo"));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use hamcrest::assert_that;
+use cargotest::support::registry::Package;
+use cargotest::support::{project, execs, basic_bin_manifest, main_file};
+
+#[test]
+fn cargo_metadata_simple() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"));
+
+ assert_that(p.cargo_process("metadata"), execs().with_json(r#"
+ {
+ "packages": [
+ {
+ "name": "foo",
+ "version": "0.5.0",
+ "id": "foo[..]",
+ "source": null,
+ "dependencies": [],
+ "targets": [
+ {
+ "kind": [
+ "bin"
+ ],
+ "name": "foo",
+ "src_path": "src[..]foo.rs"
+ }
+ ],
+ "features": {},
+ "manifest_path": "[..]Cargo.toml"
+ }
+ ],
+ "resolve": {
+ "nodes": [
+ {
+ "dependencies": [],
+ "id": "foo 0.5.0 (path+file:[..]foo)"
+ }
+ ],
+ "root": "foo 0.5.0 (path+file:[..]foo)"
+ },
+ "version": 1
+ }"#));
+}
+
+
+#[test]
+fn cargo_metadata_with_deps_and_version() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ license = "MIT"
+ description = "foo"
+
+ [[bin]]
+ name = "foo"
+
+ [dependencies]
+ bar = "*"
+ "#);
+ Package::new("baz", "0.0.1").publish();
+ Package::new("bar", "0.0.1").dep("baz", "0.0.1").publish();
+
+ assert_that(p.cargo_process("metadata")
+ .arg("-q")
+ .arg("--format-version").arg("1"),
+ execs().with_json(r#"
+ {
+ "packages": [
+ {
+ "dependencies": [],
+ "features": {},
+ "id": "baz 0.0.1 (registry+file:[..])",
+ "manifest_path": "[..]Cargo.toml",
+ "name": "baz",
+ "source": "registry+file:[..]",
+ "targets": [
+ {
+ "kind": [
+ "lib"
+ ],
+ "name": "baz",
+ "src_path": "[..]lib.rs"
+ }
+ ],
+ "version": "0.0.1"
+ },
+ {
+ "dependencies": [
+ {
+ "features": [],
+ "kind": null,
+ "name": "baz",
+ "optional": false,
+ "req": "^0.0.1",
+ "source": "registry+file:[..]",
+ "target": null,
+ "uses_default_features": true
+ }
+ ],
+ "features": {},
+ "id": "bar 0.0.1 (registry+file:[..])",
+ "manifest_path": "[..]Cargo.toml",
+ "name": "bar",
+ "source": "registry+file:[..]",
+ "targets": [
+ {
+ "kind": [
+ "lib"
+ ],
+ "name": "bar",
+ "src_path": "[..]lib.rs"
+ }
+ ],
+ "version": "0.0.1"
+ },
+ {
+ "dependencies": [
+ {
+ "features": [],
+ "kind": null,
+ "name": "bar",
+ "optional": false,
+ "req": "*",
+ "source": "registry+file:[..]",
+ "target": null,
+ "uses_default_features": true
+ }
+ ],
+ "features": {},
+ "id": "foo 0.5.0 (path+file:[..]foo)",
+ "manifest_path": "[..]Cargo.toml",
+ "name": "foo",
+ "source": null,
+ "targets": [
+ {
+ "kind": [
+ "bin"
+ ],
+ "name": "foo",
+ "src_path": "[..]foo.rs"
+ }
+ ],
+ "version": "0.5.0"
+ }
+ ],
+ "resolve": {
+ "nodes": [
+ {
+ "dependencies": [
+ "bar 0.0.1 (registry+file:[..])"
+ ],
+ "id": "foo 0.5.0 (path+file:[..]foo)"
+ },
+ {
+ "dependencies": [
+ "baz 0.0.1 (registry+file:[..])"
+ ],
+ "id": "bar 0.0.1 (registry+file:[..])"
+ },
+ {
+ "dependencies": [],
+ "id": "baz 0.0.1 (registry+file:[..])"
+ }
+ ],
+ "root": "foo 0.5.0 (path+file:[..]foo)"
+ },
+ "version": 1
+ }"#));
+}
+
+#[test]
+fn cargo_metadata_with_invalid_manifest() {
+ let p = project("foo")
+ .file("Cargo.toml", "");
+
+ assert_that(p.cargo_process("metadata"), execs().with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ no `package` or `project` section found."))
+}
+
+const MANIFEST_OUTPUT: &'static str=
+ r#"
+{
+ "packages": [{
+ "name":"foo",
+ "version":"0.5.0",
+ "id":"foo[..]0.5.0[..](path+file://[..]/foo)",
+ "source":null,
+ "dependencies":[],
+ "targets":[{
+ "kind":["bin"],
+ "name":"foo",
+ "src_path":"src[..]foo.rs"
+ }],
+ "features":{},
+ "manifest_path":"[..]Cargo.toml"
+ }],
+ "resolve": null,
+ "version": 1
+}"#;
+
+#[test]
+fn cargo_metadata_no_deps_path_to_cargo_toml_relative() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("metadata").arg("--no-deps")
+ .arg("--manifest-path").arg("foo/Cargo.toml")
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(0)
+ .with_json(MANIFEST_OUTPUT));
+}
+
+#[test]
+fn cargo_metadata_no_deps_path_to_cargo_toml_absolute() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("metadata").arg("--no-deps")
+ .arg("--manifest-path").arg(p.root().join("Cargo.toml"))
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(0)
+ .with_json(MANIFEST_OUTPUT));
+}
+
+#[test]
+fn cargo_metadata_no_deps_path_to_cargo_toml_parent_relative() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("metadata").arg("--no-deps")
+ .arg("--manifest-path").arg("foo")
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(101)
+ .with_stderr("[ERROR] the manifest-path must be \
+ a path to a Cargo.toml file"));
+}
+
+#[test]
+fn cargo_metadata_no_deps_path_to_cargo_toml_parent_absolute() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("metadata").arg("--no-deps")
+ .arg("--manifest-path").arg(p.root())
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(101)
+ .with_stderr("[ERROR] the manifest-path must be \
+ a path to a Cargo.toml file"));
+}
+
+#[test]
+fn cargo_metadata_no_deps_cwd() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("metadata").arg("--no-deps")
+ .cwd(p.root()),
+ execs().with_status(0)
+ .with_json(MANIFEST_OUTPUT));
+}
+
+#[test]
+fn carg_metadata_bad_version() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("metadata").arg("--no-deps")
+ .arg("--format-version").arg("2")
+ .cwd(p.root()),
+ execs().with_status(101)
+ .with_stderr("[ERROR] metadata version 2 not supported, only 1 is currently supported"));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use cargotest::support::{project, execs};
+use hamcrest::assert_that;
+
+#[test]
+fn net_retry_loads_from_config() {
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ git = "https://127.0.0.1:11/foo/bar"
+ "#))
+ .file("src/main.rs", "").file(".cargo/config", r#"
+ [net]
+ retry=1
+ [http]
+ timeout=1
+ "#);
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(101)
+ .with_stderr_contains(&format!("[WARNING] spurious network error \
+(1 tries remaining): [2/-1] [..]")));
+}
+
+#[test]
+fn net_retry_git_outputs_warning() {
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ git = "https://127.0.0.1:11/foo/bar"
+ "#))
+ .file(".cargo/config", r#"
+ [http]
+ timeout=1
+ "#)
+ .file("src/main.rs", "");
+
+ assert_that(p.cargo_process("build").arg("-v").arg("-j").arg("1"),
+ execs().with_status(101)
+ .with_stderr_contains(&format!("[WARNING] spurious network error \
+(2 tries remaining): [2/-1] [..]"))
+ .with_stderr_contains(&format!("\
+[WARNING] spurious network error (1 tries remaining): [2/-1] [..]")));
+}
--- /dev/null
+extern crate cargo;
+extern crate cargotest;
+extern crate hamcrest;
+extern crate tempdir;
+
+use std::fs::{self, File};
+use std::io::prelude::*;
+use std::env;
+
+use cargo::util::ProcessBuilder;
+use cargotest::process;
+use cargotest::support::{execs, paths};
+use hamcrest::{assert_that, existing_file, existing_dir, is_not};
+use tempdir::TempDir;
+
+fn cargo_process(s: &str) -> ProcessBuilder {
+ let mut p = cargotest::cargo_process();
+ p.arg(s);
+ return p;
+}
+
+#[test]
+fn simple_lib() {
+ assert_that(cargo_process("new").arg("foo").arg("--vcs").arg("none")
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+ assert_that(&paths::root().join("foo"), existing_dir());
+ assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
+ assert_that(&paths::root().join("foo/src/lib.rs"), existing_file());
+ assert_that(&paths::root().join("foo/.gitignore"), is_not(existing_file()));
+
+ assert_that(cargo_process("build").cwd(&paths::root().join("foo")),
+ execs().with_status(0));
+}
+
+#[test]
+fn simple_bin() {
+ assert_that(cargo_process("new").arg("foo").arg("--bin")
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+ assert_that(&paths::root().join("foo"), existing_dir());
+ assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
+ assert_that(&paths::root().join("foo/src/main.rs"), existing_file());
+
+ assert_that(cargo_process("build").cwd(&paths::root().join("foo")),
+ execs().with_status(0));
+ assert_that(&paths::root().join(&format!("foo/target/debug/foo{}",
+ env::consts::EXE_SUFFIX)),
+ existing_file());
+}
+
+#[test]
+fn simple_git() {
+ let td = TempDir::new("cargo").unwrap();
+ assert_that(cargo_process("new").arg("foo").cwd(td.path().clone())
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+ assert_that(td.path(), existing_dir());
+ assert_that(&td.path().join("foo/Cargo.toml"), existing_file());
+ assert_that(&td.path().join("foo/src/lib.rs"), existing_file());
+ assert_that(&td.path().join("foo/.git"), existing_dir());
+ assert_that(&td.path().join("foo/.gitignore"), existing_file());
+
+ assert_that(cargo_process("build").cwd(&td.path().clone().join("foo")),
+ execs().with_status(0));
+}
+
+#[test]
+fn no_argument() {
+ assert_that(cargo_process("new"),
+ execs().with_status(1)
+ .with_stderr("\
+[ERROR] Invalid arguments.
+
+Usage:
+ cargo new [options] <path>
+ cargo new -h | --help
+"));
+}
+
+#[test]
+fn existing() {
+ let dst = paths::root().join("foo");
+ fs::create_dir(&dst).unwrap();
+ assert_that(cargo_process("new").arg("foo"),
+ execs().with_status(101)
+ .with_stderr(format!("[ERROR] destination `{}` already exists\n",
+ dst.display())));
+}
+
+#[test]
+fn invalid_characters() {
+ assert_that(cargo_process("new").arg("foo.rs"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] Invalid character `.` in crate name: `foo.rs`
+use --name to override crate name"));
+}
+
+#[test]
+fn reserved_name() {
+ assert_that(cargo_process("new").arg("test"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] The name `test` cannot be used as a crate name\n\
+use --name to override crate name"));
+}
+
+#[test]
+fn keyword_name() {
+ assert_that(cargo_process("new").arg("pub"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] The name `pub` cannot be used as a crate name\n\
+use --name to override crate name"));
+}
+
+#[test]
+fn rust_prefix_stripped() {
+ assert_that(cargo_process("new").arg("rust-foo").env("USER", "foo"),
+ execs().with_status(0)
+ .with_stdout("note: package will be named `foo`; use --name to override"));
+ let toml = paths::root().join("rust-foo/Cargo.toml");
+ let mut contents = String::new();
+ File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"name = "foo""#));
+}
+
+#[test]
+fn bin_disables_stripping() {
+ assert_that(cargo_process("new").arg("rust-foo").arg("--bin").env("USER", "foo"),
+ execs().with_status(0));
+ let toml = paths::root().join("rust-foo/Cargo.toml");
+ let mut contents = String::new();
+ File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"name = "rust-foo""#));
+}
+
+#[test]
+fn explicit_name_not_stripped() {
+ assert_that(cargo_process("new").arg("foo").arg("--name").arg("rust-bar").env("USER", "foo"),
+ execs().with_status(0));
+ let toml = paths::root().join("foo/Cargo.toml");
+ let mut contents = String::new();
+ File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"name = "rust-bar""#));
+}
+
+#[test]
+fn finds_author_user() {
+ // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
+ // the hierarchy
+ let td = TempDir::new("cargo").unwrap();
+ assert_that(cargo_process("new").arg("foo").env("USER", "foo")
+ .cwd(td.path().clone()),
+ execs().with_status(0));
+
+ let toml = td.path().join("foo/Cargo.toml");
+ let mut contents = String::new();
+ File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"authors = ["foo"]"#));
+}
+
+#[test]
+fn finds_author_user_escaped() {
+ // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
+ // the hierarchy
+ let td = TempDir::new("cargo").unwrap();
+ assert_that(cargo_process("new").arg("foo").env("USER", "foo \"bar\"")
+ .cwd(td.path().clone()),
+ execs().with_status(0));
+
+ let toml = td.path().join("foo/Cargo.toml");
+ let mut contents = String::new();
+ File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"authors = ["foo \"bar\""]"#));
+}
+
+#[test]
+fn finds_author_username() {
+ // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
+ // the hierarchy
+ let td = TempDir::new("cargo").unwrap();
+ assert_that(cargo_process("new").arg("foo")
+ .env_remove("USER")
+ .env("USERNAME", "foo")
+ .cwd(td.path().clone()),
+ execs().with_status(0));
+
+ let toml = td.path().join("foo/Cargo.toml");
+ let mut contents = String::new();
+ File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"authors = ["foo"]"#));
+}
+
+#[test]
+fn finds_author_priority() {
+ // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
+ // the hierarchy
+ let td = TempDir::new("cargo").unwrap();
+ assert_that(cargo_process("new").arg("foo")
+ .env("USER", "bar2")
+ .env("EMAIL", "baz2")
+ .env("CARGO_NAME", "bar")
+ .env("CARGO_EMAIL", "baz")
+ .cwd(td.path().clone()),
+ execs().with_status(0));
+
+ let toml = td.path().join("foo/Cargo.toml");
+ let mut contents = String::new();
+ File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
+}
+
+#[test]
+fn finds_author_email() {
+ // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
+ // the hierarchy
+ let td = TempDir::new("cargo").unwrap();
+ assert_that(cargo_process("new").arg("foo")
+ .env("USER", "bar")
+ .env("EMAIL", "baz")
+ .cwd(td.path().clone()),
+ execs().with_status(0));
+
+ let toml = td.path().join("foo/Cargo.toml");
+ let mut contents = String::new();
+ File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
+}
+
+#[test]
+fn finds_author_git() {
+ process("git").args(&["config", "--global", "user.name", "bar"])
+ .exec().unwrap();
+ process("git").args(&["config", "--global", "user.email", "baz"])
+ .exec().unwrap();
+ assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
+ execs().with_status(0));
+
+ let toml = paths::root().join("foo/Cargo.toml");
+ let mut contents = String::new();
+ File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
+}
+
+#[test]
+fn finds_git_email() {
+ let td = TempDir::new("cargo").unwrap();
+ assert_that(cargo_process("new").arg("foo")
+ .env("GIT_AUTHOR_NAME", "foo")
+ .env("GIT_AUTHOR_EMAIL", "gitfoo")
+ .cwd(td.path().clone()),
+ execs().with_status(0));
+
+ let toml = td.path().join("foo/Cargo.toml");
+ let mut contents = String::new();
+ File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"authors = ["foo <gitfoo>"]"#), contents);
+}
+
+
+#[test]
+fn finds_git_author() {
+ // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
+ // the hierarchy
+ let td = TempDir::new("cargo").unwrap();
+ assert_that(cargo_process("new").arg("foo")
+ .env_remove("USER")
+ .env("GIT_COMMITTER_NAME", "gitfoo")
+ .cwd(td.path().clone()),
+ execs().with_status(0));
+
+ let toml = td.path().join("foo/Cargo.toml");
+ let mut contents = String::new();
+ File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"authors = ["gitfoo"]"#));
+}
+
+#[test]
+fn author_prefers_cargo() {
+ process("git").args(&["config", "--global", "user.name", "foo"])
+ .exec().unwrap();
+ process("git").args(&["config", "--global", "user.email", "bar"])
+ .exec().unwrap();
+ let root = paths::root();
+ fs::create_dir(&root.join(".cargo")).unwrap();
+ File::create(&root.join(".cargo/config")).unwrap().write_all(br#"
+ [cargo-new]
+ name = "new-foo"
+ email = "new-bar"
+ vcs = "none"
+ "#).unwrap();
+
+ assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
+ execs().with_status(0));
+
+ let toml = paths::root().join("foo/Cargo.toml");
+ let mut contents = String::new();
+ File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
+ assert!(contents.contains(r#"authors = ["new-foo <new-bar>"]"#));
+ assert!(!root.join("foo/.gitignore").exists());
+}
+
+#[test]
+fn git_prefers_command_line() {
+ let root = paths::root();
+ let td = TempDir::new("cargo").unwrap();
+ fs::create_dir(&root.join(".cargo")).unwrap();
+ File::create(&root.join(".cargo/config")).unwrap().write_all(br#"
+ [cargo-new]
+ vcs = "none"
+ name = "foo"
+ email = "bar"
+ "#).unwrap();
+
+ assert_that(cargo_process("new").arg("foo").arg("--vcs").arg("git")
+ .cwd(td.path())
+ .env("USER", "foo"),
+ execs().with_status(0));
+ assert!(td.path().join("foo/.gitignore").exists());
+}
+
+#[test]
+fn subpackage_no_git() {
+ assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
+ execs().with_status(0));
+
+ let subpackage = paths::root().join("foo").join("components");
+ fs::create_dir(&subpackage).unwrap();
+ assert_that(cargo_process("new").arg("foo/components/subcomponent")
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+ assert_that(&paths::root().join("foo/components/subcomponent/.git"),
+ is_not(existing_file()));
+ assert_that(&paths::root().join("foo/components/subcomponent/.gitignore"),
+ is_not(existing_file()));
+}
+
+#[test]
+fn subpackage_git_with_vcs_arg() {
+ assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
+ execs().with_status(0));
+
+ let subpackage = paths::root().join("foo").join("components");
+ fs::create_dir(&subpackage).unwrap();
+ assert_that(cargo_process("new").arg("foo/components/subcomponent")
+ .arg("--vcs").arg("git")
+ .env("USER", "foo"),
+ execs().with_status(0));
+
+ assert_that(&paths::root().join("foo/components/subcomponent/.git"),
+ existing_dir());
+ assert_that(&paths::root().join("foo/components/subcomponent/.gitignore"),
+ existing_file());
+}
+
+#[test]
+fn unknown_flags() {
+ assert_that(cargo_process("new").arg("foo").arg("--flag"),
+ execs().with_status(1)
+ .with_stderr("\
+[ERROR] Unknown flag: '--flag'
+
+Usage:
+ cargo new [..]
+ cargo new [..]
+"));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use cargotest::support::git;
+use cargotest::support::paths;
+use cargotest::support::registry::{registry, Package};
+use cargotest::support::{execs, project};
+use hamcrest::assert_that;
+
+#[test]
+fn override_simple() {
+ Package::new("foo", "0.1.0").publish();
+
+ let foo = git::repo(&paths::root().join("override"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn foo() {}");
+ foo.build();
+
+ let p = project("local")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ foo = "0.1.0"
+
+ [replace]
+ "foo:0.1.0" = {{ git = '{}' }}
+ "#, foo.url()))
+ .file("src/lib.rs", "
+ extern crate foo;
+ pub fn bar() {
+ foo::foo();
+ }
+ ");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry `file://[..]`
+[UPDATING] git repository `[..]`
+[COMPILING] foo v0.1.0 (file://[..])
+[COMPILING] local v0.0.1 (file://[..])
+"));
+}
+
+#[test]
+fn missing_version() {
+ let p = project("local")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ foo = "0.1.0"
+
+ [replace]
+ foo = { git = 'https://example.com' }
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+error: failed to parse manifest at `[..]`
+
+Caused by:
+ replacements must specify a version to replace, but `foo` does not
+"));
+}
+
+#[test]
+fn different_version() {
+ Package::new("foo", "0.2.0").publish();
+ Package::new("foo", "0.1.0").publish();
+
+ let p = project("local")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ foo = "0.1.0"
+
+ [replace]
+ "foo:0.1.0" = "0.2.0"
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+error: failed to parse manifest at `[..]`
+
+Caused by:
+ replacements cannot specify a version requirement, but found one for [..]
+"));
+}
+
+#[test]
+fn transitive() {
+ Package::new("foo", "0.1.0").publish();
+ Package::new("bar", "0.2.0")
+ .dep("foo", "0.1.0")
+ .file("src/lib.rs", "extern crate foo; fn bar() { foo::foo(); }")
+ .publish();
+
+ let foo = git::repo(&paths::root().join("override"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn foo() {}");
+ foo.build();
+
+ let p = project("local")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "0.2.0"
+
+ [replace]
+ "foo:0.1.0" = {{ git = '{}' }}
+ "#, foo.url()))
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry `file://[..]`
+[UPDATING] git repository `[..]`
+[DOWNLOADING] bar v0.2.0 (registry [..])
+[COMPILING] foo v0.1.0 (file://[..])
+[COMPILING] bar v0.2.0 (registry [..])
+[COMPILING] local v0.0.1 (file://[..])
+"));
+
+ assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
+}
+
+#[test]
+fn persists_across_rebuilds() {
+ Package::new("foo", "0.1.0").publish();
+
+ let foo = git::repo(&paths::root().join("override"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn foo() {}");
+ foo.build();
+
+ let p = project("local")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ foo = "0.1.0"
+
+ [replace]
+ "foo:0.1.0" = {{ git = '{}' }}
+ "#, foo.url()))
+ .file("src/lib.rs", "
+ extern crate foo;
+ pub fn bar() {
+ foo::foo();
+ }
+ ");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry `file://[..]`
+[UPDATING] git repository `file://[..]`
+[COMPILING] foo v0.1.0 (file://[..])
+[COMPILING] local v0.0.1 (file://[..])
+"));
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stdout(""));
+}
+
+#[test]
+fn replace_registry_with_path() {
+ Package::new("foo", "0.1.0").publish();
+
+ project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn foo() {}")
+ .build();
+
+ let p = project("local")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ foo = "0.1.0"
+
+ [replace]
+ "foo:0.1.0" = { path = "../foo" }
+ "#)
+ .file("src/lib.rs", "
+ extern crate foo;
+ pub fn bar() {
+ foo::foo();
+ }
+ ");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry `file://[..]`
+[COMPILING] foo v0.1.0 (file://[..])
+[COMPILING] local v0.0.1 (file://[..])
+"));
+}
+
+#[test]
+fn use_a_spec_to_select() {
+ Package::new("foo", "0.1.1")
+ .file("src/lib.rs", "pub fn foo1() {}")
+ .publish();
+ Package::new("foo", "0.2.0").publish();
+ Package::new("bar", "0.1.1")
+ .dep("foo", "0.2")
+ .file("src/lib.rs", "
+ extern crate foo;
+ pub fn bar() { foo::foo3(); }
+ ")
+ .publish();
+
+ let foo = git::repo(&paths::root().join("override"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.2.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn foo3() {}");
+ foo.build();
+
+ let p = project("local")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "0.1"
+ foo = "0.1"
+
+ [replace]
+ "foo:0.2.0" = {{ git = '{}' }}
+ "#, foo.url()))
+ .file("src/lib.rs", "
+ extern crate foo;
+ extern crate bar;
+
+ pub fn local() {
+ foo::foo1();
+ bar::bar();
+ }
+ ");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry `file://[..]`
+[UPDATING] git repository `[..]`
+[DOWNLOADING] [..]
+[DOWNLOADING] [..]
+[COMPILING] [..]
+[COMPILING] [..]
+[COMPILING] [..]
+[COMPILING] local v0.0.1 (file://[..])
+"));
+}
+
+#[test]
+fn override_adds_some_deps() {
+ Package::new("foo", "0.1.1").publish();
+ Package::new("bar", "0.1.0").publish();
+
+ let foo = git::repo(&paths::root().join("override"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ foo = "0.1"
+ "#)
+ .file("src/lib.rs", "");
+ foo.build();
+
+ let p = project("local")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "0.1"
+
+ [replace]
+ "bar:0.1.0" = {{ git = '{}' }}
+ "#, foo.url()))
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry `file://[..]`
+[UPDATING] git repository `[..]`
+[DOWNLOADING] foo v0.1.1 (registry [..])
+[COMPILING] foo v0.1.1 (registry [..])
+[COMPILING] bar v0.1.0 ([..])
+[COMPILING] local v0.0.1 (file://[..])
+"));
+
+ assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
+
+ Package::new("foo", "0.1.2").publish();
+ assert_that(p.cargo("update").arg("-p").arg(&format!("{}#bar", foo.url())),
+ execs().with_status(0).with_stderr("\
+[UPDATING] git repository `file://[..]`
+"));
+ assert_that(p.cargo("update").arg("-p").arg(&format!("{}#bar", registry())),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry `file://[..]`
+"));
+
+ assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
+}
+
+#[test]
+fn locked_means_locked_yes_no_seriously_i_mean_locked() {
+ // this in theory exercises #2041
+ Package::new("foo", "0.1.0").publish();
+ Package::new("foo", "0.2.0").publish();
+ Package::new("bar", "0.1.0").publish();
+
+ let foo = git::repo(&paths::root().join("override"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ foo = "*"
+ "#)
+ .file("src/lib.rs", "");
+ foo.build();
+
+ let p = project("local")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ foo = "0.1"
+ bar = "0.1"
+
+ [replace]
+ "bar:0.1.0" = {{ git = '{}' }}
+ "#, foo.url()))
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0));
+
+ assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
+ assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
+}
+
+#[test]
+fn override_wrong_name() {
+ Package::new("foo", "0.1.0").publish();
+
+ let foo = git::repo(&paths::root().join("override"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "");
+ foo.build();
+
+ let p = project("local")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ foo = "0.1"
+
+ [replace]
+ "foo:0.1.0" = {{ git = '{}' }}
+ "#, foo.url()))
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[UPDATING] registry [..]
+[UPDATING] git repository [..]
+error: no matching package for override `foo:0.1.0` found
+location searched: file://[..]
+version required: = 0.1.0
+"));
+}
+
+#[test]
+fn override_with_nothing() {
+ Package::new("foo", "0.1.0").publish();
+
+ let foo = git::repo(&paths::root().join("override"))
+ .file("src/lib.rs", "");
+ foo.build();
+
+ let p = project("local")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ foo = "0.1"
+
+ [replace]
+ "foo:0.1.0" = {{ git = '{}' }}
+ "#, foo.url()))
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[UPDATING] registry [..]
+[UPDATING] git repository [..]
+error: Unable to update file://[..]
+
+Caused by:
+ Could not find Cargo.toml in `[..]`
+"));
+}
+
+#[test]
+fn override_wrong_version() {
+ let p = project("local")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [replace]
+ "foo:0.1.0" = { git = 'https://example.com', version = '0.2.0' }
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+error: failed to parse manifest at `[..]`
+
+Caused by:
+ replacements cannot specify a version requirement, but found one for `foo:0.1.0`
+"));
+}
+
+#[test]
+fn multiple_specs() {
+ Package::new("foo", "0.1.0").publish();
+
+ let foo = git::repo(&paths::root().join("override"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn foo() {}");
+ foo.build();
+
+ let p = project("local")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ foo = "0.1.0"
+
+ [replace]
+ "foo:0.1.0" = {{ git = '{0}' }}
+ "{1}#foo:0.1.0" = {{ git = '{0}' }}
+ "#, foo.url(), registry()))
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[UPDATING] registry [..]
+[UPDATING] git repository [..]
+error: overlapping replacement specifications found:
+
+ * [..]
+ * [..]
+
+both specifications match: foo v0.1.0 ([..])
+"));
+}
+
+#[test]
+fn test_override_dep() {
+ Package::new("foo", "0.1.0").publish();
+
+ let foo = git::repo(&paths::root().join("override"))
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "pub fn foo() {}");
+ foo.build();
+
+ let p = project("local")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+ name = "local"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ foo = "0.1.0"
+
+ [replace]
+ "foo:0.1.0" = {{ git = '{0}' }}
+ "#, foo.url()))
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("test").arg("-p").arg("foo"),
+ execs().with_status(101)
+ .with_stderr_contains("\
+error: There are multiple `foo` packages in your project, and the [..]
+Please re-run this command with [..]
+ [..]#foo:0.1.0
+ [..]#foo:0.1.0
+"));
+}
--- /dev/null
+extern crate cargotest;
+extern crate flate2;
+extern crate git2;
+extern crate hamcrest;
+extern crate tar;
+
+use std::fs::File;
+use std::io::prelude::*;
+use std::path::Path;
+
+use cargotest::cargo_process;
+use cargotest::support::{project, execs, paths, git, path2url};
+use flate2::read::GzDecoder;
+use hamcrest::{assert_that, existing_file};
+use tar::Archive;
+
+#[test]
+fn simple() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ exclude = ["*.txt"]
+ license = "MIT"
+ description = "foo"
+ "#)
+ .file("src/main.rs", r#"
+ fn main() { println!("hello"); }
+ "#)
+ .file("src/bar.txt", ""); // should be ignored when packaging
+
+ assert_that(p.cargo_process("package"),
+ execs().with_status(0).with_stderr(&format!("\
+[WARNING] manifest has no documentation[..]
+[PACKAGING] foo v0.0.1 ({dir})
+[VERIFYING] foo v0.0.1 ({dir})
+[COMPILING] foo v0.0.1 ({dir}[..])
+",
+ dir = p.url())));
+ assert_that(&p.root().join("target/package/foo-0.0.1.crate"), existing_file());
+ assert_that(p.cargo("package").arg("-l"),
+ execs().with_status(0).with_stdout("\
+Cargo.toml
+src[..]main.rs
+"));
+ assert_that(p.cargo("package"),
+ execs().with_status(0).with_stdout(""));
+
+ let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap();
+ let mut rdr = GzDecoder::new(f).unwrap();
+ let mut contents = Vec::new();
+ rdr.read_to_end(&mut contents).unwrap();
+ let mut ar = Archive::new(&contents[..]);
+ for f in ar.entries().unwrap() {
+ let f = f.unwrap();
+ let fname = f.header().path_bytes();
+ let fname = &*fname;
+ assert!(fname == b"foo-0.0.1/Cargo.toml" ||
+ fname == b"foo-0.0.1/src/main.rs",
+ "unexpected filename: {:?}", f.header().path())
+ }
+}
+
+#[test]
+fn metadata_warning() {
+ let p = project("all")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#);
+ assert_that(p.cargo_process("package"),
+ execs().with_status(0).with_stderr(&format!("\
+warning: manifest has no description, license, license-file, documentation, \
+homepage or repository. See \
+http://doc.crates.io/manifest.html#package-metadata for more info.
+[PACKAGING] foo v0.0.1 ({dir})
+[VERIFYING] foo v0.0.1 ({dir})
+[COMPILING] foo v0.0.1 ({dir}[..])
+",
+ dir = p.url())));
+
+ let p = project("one")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#);
+ assert_that(p.cargo_process("package"),
+ execs().with_status(0).with_stderr(&format!("\
+warning: manifest has no description, documentation, homepage or repository. See \
+http://doc.crates.io/manifest.html#package-metadata for more info.
+[PACKAGING] foo v0.0.1 ({dir})
+[VERIFYING] foo v0.0.1 ({dir})
+[COMPILING] foo v0.0.1 ({dir}[..])
+",
+ dir = p.url())));
+
+ let p = project("all")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "foo"
+ repository = "bar"
+ "#))
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#);
+ assert_that(p.cargo_process("package"),
+ execs().with_status(0).with_stderr(&format!("\
+[PACKAGING] foo v0.0.1 ({dir})
+[VERIFYING] foo v0.0.1 ({dir})
+[COMPILING] foo v0.0.1 ({dir}[..])
+",
+ dir = p.url())));
+}
+
+#[test]
+fn package_verbose() {
+ let root = paths::root().join("all");
+ let p = git::repo(&root)
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "");
+ p.build();
+ let mut cargo = cargo_process();
+ cargo.cwd(p.root());
+ assert_that(cargo.clone().arg("build"), execs().with_status(0));
+
+ println!("package main repo");
+ assert_that(cargo.clone().arg("package").arg("-v").arg("--no-verify"),
+ execs().with_status(0).with_stderr("\
+[WARNING] manifest has no description[..]
+[PACKAGING] foo v0.0.1 ([..])
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+"));
+
+ println!("package sub-repo");
+ assert_that(cargo.arg("package").arg("-v").arg("--no-verify")
+ .cwd(p.root().join("a")),
+ execs().with_status(0).with_stderr("\
+[WARNING] manifest has no description[..]
+[PACKAGING] a v0.0.1 ([..])
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+"));
+}
+
+#[test]
+fn package_verification() {
+ let p = project("all")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#);
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0));
+ assert_that(p.cargo("package"),
+ execs().with_status(0).with_stderr(&format!("\
+[WARNING] manifest has no description[..]
+[PACKAGING] foo v0.0.1 ({dir})
+[VERIFYING] foo v0.0.1 ({dir})
+[COMPILING] foo v0.0.1 ({dir}[..])
+",
+ dir = p.url())));
+}
+
+#[test]
+fn exclude() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ exclude = ["*.txt"]
+ "#)
+ .file("src/main.rs", r#"
+ fn main() { println!("hello"); }
+ "#)
+ .file("bar.txt", "")
+ .file("src/bar.txt", "");
+
+ assert_that(p.cargo_process("package").arg("--no-verify").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[WARNING] manifest has no description[..]
+[PACKAGING] foo v0.0.1 ([..])
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+"));
+}
+
+#[test]
+fn include() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ exclude = ["*.txt"]
+ include = ["foo.txt", "**/*.rs", "Cargo.toml"]
+ "#)
+ .file("foo.txt", "")
+ .file("src/main.rs", r#"
+ fn main() { println!("hello"); }
+ "#)
+ .file("src/bar.txt", ""); // should be ignored when packaging
+
+ assert_that(p.cargo_process("package").arg("--no-verify").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[WARNING] manifest has no description[..]
+[PACKAGING] foo v0.0.1 ([..])
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+"));
+}
+
+#[test]
+fn package_lib_with_bin() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ extern crate foo;
+ fn main() {}
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("package").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn package_new_git_repo() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+ git2::Repository::init(&p.root()).unwrap();
+
+ assert_that(cargo_process().arg("package").cwd(p.root())
+ .arg("--no-verify").arg("-v"),
+ execs().with_status(0).with_stderr("\
+[WARNING] manifest has no description[..]
+[PACKAGING] foo v0.0.1 ([..])
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+"));
+}
+
+#[test]
+fn package_git_submodule() {
+ let project = git::new("foo", |project| {
+ project.file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = ["foo@example.com"]
+ license = "MIT"
+ description = "foo"
+ repository = "foo"
+ "#)
+ .file("src/lib.rs", "pub fn foo() {}")
+ }).unwrap();
+ let library = git::new("bar", |library| {
+ library.file("Makefile", "all:")
+ }).unwrap();
+
+ let repository = git2::Repository::open(&project.root()).unwrap();
+ let url = path2url(library.root()).to_string();
+ git::add_submodule(&repository, &url, Path::new("bar"));
+ git::commit(&repository);
+
+ let repository = git2::Repository::open(&project.root().join("bar")).unwrap();
+ repository.reset(&repository.revparse_single("HEAD").unwrap(),
+ git2::ResetType::Hard, None).unwrap();
+
+ assert_that(cargo_process().arg("package").cwd(project.root())
+ .arg("--no-verify").arg("-v"),
+ execs().with_status(0).with_stderr_contains("[ARCHIVING] bar/Makefile"));
+}
+
+#[test]
+fn no_duplicates_from_modified_tracked_files() {
+ let root = paths::root().join("all");
+ let p = git::repo(&root)
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#);
+ p.build();
+ File::create(p.root().join("src/main.rs")).unwrap().write_all(r#"
+ fn main() { println!("A change!"); }
+ "#.as_bytes()).unwrap();
+ let mut cargo = cargo_process();
+ cargo.cwd(p.root());
+ assert_that(cargo.clone().arg("build"), execs().with_status(0));
+ assert_that(cargo.arg("package").arg("--list"),
+ execs().with_status(0).with_stdout("\
+Cargo.toml
+src/main.rs
+"));
+}
+
+#[test]
+fn ignore_nested() {
+ let cargo_toml = r#"
+ [project]
+ name = "nested"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "nested"
+ "#;
+ let main_rs = r#"
+ fn main() { println!("hello"); }
+ "#;
+ let p = project("nested")
+ .file("Cargo.toml", cargo_toml)
+ .file("src/main.rs", main_rs)
+ // If a project happens to contain a copy of itself, we should
+ // ignore it.
+ .file("a_dir/nested/Cargo.toml", cargo_toml)
+ .file("a_dir/nested/src/main.rs", main_rs);
+
+ assert_that(p.cargo_process("package"),
+ execs().with_status(0).with_stderr(&format!("\
+[WARNING] manifest has no documentation[..]
+[PACKAGING] nested v0.0.1 ({dir})
+[VERIFYING] nested v0.0.1 ({dir})
+[COMPILING] nested v0.0.1 ({dir}[..])
+",
+ dir = p.url())));
+ assert_that(&p.root().join("target/package/nested-0.0.1.crate"), existing_file());
+ assert_that(p.cargo("package").arg("-l"),
+ execs().with_status(0).with_stdout("\
+Cargo.toml
+src[..]main.rs
+"));
+ assert_that(p.cargo("package"),
+ execs().with_status(0).with_stdout(""));
+
+ let f = File::open(&p.root().join("target/package/nested-0.0.1.crate")).unwrap();
+ let mut rdr = GzDecoder::new(f).unwrap();
+ let mut contents = Vec::new();
+ rdr.read_to_end(&mut contents).unwrap();
+ let mut ar = Archive::new(&contents[..]);
+ for f in ar.entries().unwrap() {
+ let f = f.unwrap();
+ let fname = f.header().path_bytes();
+ let fname = &*fname;
+ assert!(fname == b"nested-0.0.1/Cargo.toml" ||
+ fname == b"nested-0.0.1/src/main.rs",
+ "unexpected filename: {:?}", f.header().path())
+ }
+}
+
+#[cfg(unix)] // windows doesn't allow these characters in filenames
+#[test]
+fn package_weird_characters() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() { println!("hello"); }
+ "#)
+ .file("src/:foo", "");
+
+ assert_that(p.cargo_process("package"),
+ execs().with_status(101).with_stderr("\
+warning: [..]
+[PACKAGING] foo [..]
+[ERROR] failed to prepare local package for uploading
+
+Caused by:
+ cannot package a filename with a special character `:`: src/:foo
+"));
+}
--- /dev/null
+extern crate cargo;
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::fs::{self, File};
+use std::io::prelude::*;
+
+use cargo::util::process;
+use cargotest::sleep_ms;
+use cargotest::support::paths::{self, CargoPathExt};
+use cargotest::support::{project, execs, main_file};
+use hamcrest::{assert_that, existing_file};
+
+#[test]
+fn cargo_compile_with_nested_deps_shorthand() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+
+ version = "0.5.0"
+ path = "bar"
+
+ [[bin]]
+
+ name = "foo"
+ "#)
+ .file("src/foo.rs",
+ &main_file(r#""{}", bar::gimme()"#, &["bar"]))
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.baz]
+
+ version = "0.5.0"
+ path = "baz"
+
+ [lib]
+
+ name = "bar"
+ "#)
+ .file("bar/src/bar.rs", r#"
+ extern crate baz;
+
+ pub fn gimme() -> String {
+ baz::gimme()
+ }
+ "#)
+ .file("bar/baz/Cargo.toml", r#"
+ [project]
+
+ name = "baz"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib]
+
+ name = "baz"
+ "#)
+ .file("bar/baz/src/baz.rs", r#"
+ pub fn gimme() -> String {
+ "test passed".to_string()
+ }
+ "#);
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0)
+ .with_stderr(&format!("[COMPILING] baz v0.5.0 ({}/bar/baz)\n\
+ [COMPILING] bar v0.5.0 ({}/bar)\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ p.url(),
+ p.url(),
+ p.url())));
+
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("test passed\n").with_status(0));
+
+ println!("cleaning");
+ assert_that(p.cargo("clean"),
+ execs().with_stdout("").with_status(0));
+ println!("building baz");
+ assert_that(p.cargo("build").arg("-p").arg("baz"),
+ execs().with_status(0)
+ .with_stderr(&format!("[COMPILING] baz v0.5.0 ({}/bar/baz)\n",
+ p.url())));
+ println!("building foo");
+ assert_that(p.cargo("build")
+ .arg("-p").arg("foo"),
+ execs().with_status(0)
+ .with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ p.url(),
+ p.url())));
+}
+
+#[test]
+fn cargo_compile_with_root_dev_deps() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dev-dependencies.bar]
+
+ version = "0.5.0"
+ path = "../bar"
+
+ [[bin]]
+ name = "foo"
+ "#)
+ .file("src/main.rs",
+ &main_file(r#""{}", bar::gimme()"#, &["bar"]));
+ let p2 = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn gimme() -> &'static str {
+ "zoidberg"
+ }
+ "#);
+
+ p2.build();
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101))
+}
+
+#[test]
+fn cargo_compile_with_root_dev_deps_with_testing() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dev-dependencies.bar]
+
+ version = "0.5.0"
+ path = "../bar"
+
+ [[bin]]
+ name = "foo"
+ "#)
+ .file("src/main.rs",
+ &main_file(r#""{}", bar::gimme()"#, &["bar"]));
+ let p2 = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn gimme() -> &'static str {
+ "zoidberg"
+ }
+ "#);
+
+ p2.build();
+ assert_that(p.cargo_process("test"),
+ execs().with_stderr("\
+[COMPILING] [..] v0.5.0 ([..])
+[COMPILING] [..] v0.5.0 ([..])
+[RUNNING] target[..]foo-[..]")
+ .with_stdout("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn cargo_compile_with_transitive_dev_deps() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+
+ version = "0.5.0"
+ path = "bar"
+
+ [[bin]]
+
+ name = "foo"
+ "#)
+ .file("src/foo.rs",
+ &main_file(r#""{}", bar::gimme()"#, &["bar"]))
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dev-dependencies.baz]
+
+ git = "git://example.com/path/to/nowhere"
+
+ [lib]
+
+ name = "bar"
+ "#)
+ .file("bar/src/bar.rs", r#"
+ pub fn gimme() -> &'static str {
+ "zoidberg"
+ }
+ "#);
+
+ assert_that(p.cargo_process("build"),
+ execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ p.url(),
+ p.url())));
+
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("zoidberg\n"));
+}
+
+#[test]
+fn no_rebuild_dependency() {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [[bin]] name = "foo"
+ [dependencies.bar] path = "bar"
+ "#)
+ .file("src/foo.rs", r#"
+ extern crate bar;
+ fn main() { bar::bar() }
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib] name = "bar"
+ "#)
+ .file("bar/src/bar.rs", r#"
+ pub fn bar() {}
+ "#);
+ // First time around we should compile both foo and bar
+ assert_that(p.cargo_process("build"),
+ execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ p.url(),
+ p.url())));
+ // This time we shouldn't compile bar
+ assert_that(p.cargo("build"),
+ execs().with_stdout(""));
+ p.root().move_into_the_past();
+
+ p.build(); // rebuild the files (rewriting them in the process)
+ assert_that(p.cargo("build"),
+ execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ p.url(),
+ p.url())));
+}
+
+#[test]
+fn deep_dependencies_trigger_rebuild() {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [[bin]]
+ name = "foo"
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/foo.rs", r#"
+ extern crate bar;
+ fn main() { bar::bar() }
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib]
+ name = "bar"
+ [dependencies.baz]
+ path = "../baz"
+ "#)
+ .file("bar/src/bar.rs", r#"
+ extern crate baz;
+ pub fn bar() { baz::baz() }
+ "#)
+ .file("baz/Cargo.toml", r#"
+ [project]
+
+ name = "baz"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib]
+ name = "baz"
+ "#)
+ .file("baz/src/baz.rs", r#"
+ pub fn baz() {}
+ "#);
+ assert_that(p.cargo_process("build"),
+ execs().with_stderr(&format!("[COMPILING] baz v0.5.0 ({}/baz)\n\
+ [COMPILING] bar v0.5.0 ({}/bar)\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ p.url(),
+ p.url(),
+ p.url())));
+ assert_that(p.cargo("build"),
+ execs().with_stdout(""));
+
+ // Make sure an update to baz triggers a rebuild of bar
+ //
+ // We base recompilation off mtime, so sleep for at least a second to ensure
+ // that this write will change the mtime.
+ sleep_ms(1000);
+ File::create(&p.root().join("baz/src/baz.rs")).unwrap().write_all(br#"
+ pub fn baz() { println!("hello!"); }
+ "#).unwrap();
+ assert_that(p.cargo("build"),
+ execs().with_stderr(&format!("[COMPILING] baz v0.5.0 ({}/baz)\n\
+ [COMPILING] bar v0.5.0 ({}/bar)\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ p.url(),
+ p.url(),
+ p.url())));
+
+ // Make sure an update to bar doesn't trigger baz
+ sleep_ms(1000);
+ File::create(&p.root().join("bar/src/bar.rs")).unwrap().write_all(br#"
+ extern crate baz;
+ pub fn bar() { println!("hello!"); baz::baz(); }
+ "#).unwrap();
+ assert_that(p.cargo("build"),
+ execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ p.url(),
+ p.url())));
+
+}
+
+#[test]
+fn no_rebuild_two_deps() {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [[bin]]
+ name = "foo"
+ [dependencies.bar]
+ path = "bar"
+ [dependencies.baz]
+ path = "baz"
+ "#)
+ .file("src/foo.rs", r#"
+ extern crate bar;
+ fn main() { bar::bar() }
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib]
+ name = "bar"
+ [dependencies.baz]
+ path = "../baz"
+ "#)
+ .file("bar/src/bar.rs", r#"
+ pub fn bar() {}
+ "#)
+ .file("baz/Cargo.toml", r#"
+ [project]
+
+ name = "baz"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib]
+ name = "baz"
+ "#)
+ .file("baz/src/baz.rs", r#"
+ pub fn baz() {}
+ "#);
+ assert_that(p.cargo_process("build"),
+ execs().with_stderr(&format!("[COMPILING] baz v0.5.0 ({}/baz)\n\
+ [COMPILING] bar v0.5.0 ({}/bar)\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ p.url(),
+ p.url(),
+ p.url())));
+ assert_that(&p.bin("foo"), existing_file());
+ assert_that(p.cargo("build"),
+ execs().with_stdout(""));
+ assert_that(&p.bin("foo"), existing_file());
+}
+
+#[test]
+fn nested_deps_recompile() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+
+ version = "0.5.0"
+ path = "src/bar"
+
+ [[bin]]
+
+ name = "foo"
+ "#)
+ .file("src/foo.rs",
+ &main_file(r#""{}", bar::gimme()"#, &["bar"]))
+ .file("src/bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [lib]
+
+ name = "bar"
+ "#)
+ .file("src/bar/src/bar.rs", "pub fn gimme() -> i32 { 92 }");
+ let bar = p.url();
+
+ assert_that(p.cargo_process("build"),
+ execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/src/bar)\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ bar,
+ p.url())));
+ sleep_ms(1000);
+
+ File::create(&p.root().join("src/foo.rs")).unwrap().write_all(br#"
+ fn main() {}
+ "#).unwrap();
+
+ // This shouldn't recompile `bar`
+ assert_that(p.cargo("build"),
+ execs().with_stderr(&format!("[COMPILING] foo v0.5.0 ({})\n",
+ p.url())));
+}
+
+#[test]
+fn error_message_for_missing_manifest() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+
+ path = "src/bar"
+
+ [lib]
+
+ name = "foo"
+ "#)
+ .file("src/bar/not-a-manifest", "");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] Unable to update file://[..]
+
+Caused by:
+ failed to read `[..]bar[..]Cargo.toml`
+
+Caused by:
+ [..] (os error [..])
+"));
+
+}
+
+#[test]
+fn override_relative() {
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", "");
+
+ fs::create_dir(&paths::root().join(".cargo")).unwrap();
+ File::create(&paths::root().join(".cargo/config")).unwrap()
+ .write_all(br#"paths = ["bar"]"#).unwrap();
+
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [package]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+ path = '{}'
+ "#, bar.root().display()))
+ .file("src/lib.rs", "");
+ bar.build();
+ assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0));
+
+}
+
+#[test]
+fn override_self() {
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("src/lib.rs", "");
+
+ let p = project("foo");
+ let root = p.root().clone();
+ let p = p
+ .file(".cargo/config", &format!(r#"
+ paths = ['{}']
+ "#, root.display()))
+ .file("Cargo.toml", &format!(r#"
+ [package]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+ path = '{}'
+
+ "#, bar.root().display()))
+ .file("src/lib.rs", "")
+ .file("src/main.rs", "fn main() {}");
+
+ bar.build();
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+
+}
+
+#[test]
+fn override_path_dep() {
+ let bar = project("bar")
+ .file("p1/Cargo.toml", r#"
+ [package]
+ name = "p1"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies.p2]
+ path = "../p2"
+ "#)
+ .file("p1/src/lib.rs", "")
+ .file("p2/Cargo.toml", r#"
+ [package]
+ name = "p2"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("p2/src/lib.rs", "");
+
+ let p = project("foo")
+ .file(".cargo/config", &format!(r#"
+ paths = ['{}', '{}']
+ "#, bar.root().join("p1").display(),
+ bar.root().join("p2").display()))
+ .file("Cargo.toml", &format!(r#"
+ [package]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.p2]
+ path = '{}'
+
+ "#, bar.root().join("p2").display()))
+ .file("src/lib.rs", "");
+
+ bar.build();
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+
+}
+
+#[test]
+fn path_dep_build_cmd() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+
+ version = "0.5.0"
+ path = "bar"
+
+ [[bin]]
+
+ name = "foo"
+ "#)
+ .file("src/foo.rs",
+ &main_file(r#""{}", bar::gimme()"#, &["bar"]))
+ .file("bar/Cargo.toml", r#"
+ [project]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ build = "build.rs"
+
+ [lib]
+
+ name = "bar"
+ "#)
+ .file("bar/build.rs", r#"
+ use std::fs;
+ fn main() {
+ fs::copy("src/bar.rs.in", "src/bar.rs").unwrap();
+ }
+ "#)
+ .file("bar/src/bar.rs.in", r#"
+ pub fn gimme() -> i32 { 0 }
+ "#);
+
+ p.build();
+ p.root().join("bar").move_into_the_past();
+
+ assert_that(p.cargo("build"),
+ execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ p.url(),
+ p.url())));
+
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("0\n"));
+
+ // Touching bar.rs.in should cause the `build` command to run again.
+ {
+ let file = fs::File::create(&p.root().join("bar/src/bar.rs.in"));
+ file.unwrap().write_all(br#"pub fn gimme() -> i32 { 1 }"#).unwrap();
+ }
+
+ assert_that(p.cargo("build"),
+ execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
+ [COMPILING] foo v0.5.0 ({})\n",
+ p.url(),
+ p.url())));
+
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("1\n"));
+}
+
+#[test]
+fn dev_deps_no_rebuild_lib() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dev-dependencies.bar]
+ path = "bar"
+
+ [lib]
+ name = "foo"
+ doctest = false
+ "#)
+ .file("src/lib.rs", r#"
+ #[cfg(test)] extern crate bar;
+ #[cfg(not(test))] pub fn foo() { env!("FOO"); }
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ "#)
+ .file("bar/src/lib.rs", "pub fn bar() {}");
+ p.build();
+ assert_that(p.cargo("build")
+ .env("FOO", "bar"),
+ execs().with_status(0)
+ .with_stderr(&format!("[COMPILING] foo v0.5.0 ({})\n",
+ p.url())));
+
+ assert_that(p.cargo("test"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] [..] v0.5.0 ({url}[..])
+[COMPILING] [..] v0.5.0 ({url}[..])
+[RUNNING] target[..]foo-[..]", url = p.url()))
+ .with_stdout("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn custom_target_no_rebuild() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ [dependencies]
+ a = { path = "a" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "")
+ .file("b/Cargo.toml", r#"
+ [project]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+ [dependencies]
+ a = { path = "../a" }
+ "#)
+ .file("b/src/lib.rs", "");
+ p.build();
+ assert_that(p.cargo("build"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] a v0.5.0 ([..])
+[COMPILING] foo v0.5.0 ([..])
+"));
+
+ assert_that(p.cargo("build")
+ .arg("--manifest-path=b/Cargo.toml")
+ .env("CARGO_TARGET_DIR", "target"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] b v0.5.0 ([..])
+"));
+}
+
+#[test]
+fn override_and_depend() {
+ let p = project("foo")
+ .file("a/a1/Cargo.toml", r#"
+ [project]
+ name = "a1"
+ version = "0.5.0"
+ authors = []
+ [dependencies]
+ a2 = { path = "../a2" }
+ "#)
+ .file("a/a1/src/lib.rs", "")
+ .file("a/a2/Cargo.toml", r#"
+ [project]
+ name = "a2"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("a/a2/src/lib.rs", "")
+ .file("b/Cargo.toml", r#"
+ [project]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+ [dependencies]
+ a1 = { path = "../a/a1" }
+ a2 = { path = "../a/a2" }
+ "#)
+ .file("b/src/lib.rs", "")
+ .file("b/.cargo/config", r#"
+ paths = ["../a"]
+ "#);
+ p.build();
+ assert_that(p.cargo("build").cwd(p.root().join("b")),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] a2 v0.5.0 ([..])
+[COMPILING] a1 v0.5.0 ([..])
+[COMPILING] b v0.5.0 ([..])
+"));
+}
+
+#[test]
+fn missing_path_dependency() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", r#"
+ paths = ["../whoa-this-does-not-exist"]
+ "#);
+ p.build();
+ assert_that(p.cargo("build"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] failed to update path override `[..]../whoa-this-does-not-exist` \
+(defined in `[..]`)
+
+Caused by:
+ failed to read directory `[..]`
+
+Caused by:
+ [..] (os error [..])
+"));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::fs;
+use std::env;
+
+use cargotest::{is_nightly, rustc_host};
+use cargotest::support::{project, execs};
+use hamcrest::assert_that;
+
+#[test]
+fn plugin_to_the_max() {
+ if !is_nightly() { return }
+
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo_lib"
+
+ [dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/main.rs", r#"
+ #![feature(plugin)]
+ #![plugin(bar)]
+ extern crate foo_lib;
+
+ fn main() { foo_lib::foo(); }
+ "#)
+ .file("src/foo_lib.rs", r#"
+ #![feature(plugin)]
+ #![plugin(bar)]
+
+ pub fn foo() {}
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "bar"
+ plugin = true
+
+ [dependencies.baz]
+ path = "../baz"
+ "#)
+ .file("src/lib.rs", r#"
+ #![feature(plugin_registrar, rustc_private)]
+
+ extern crate rustc_plugin;
+ extern crate baz;
+
+ use rustc_plugin::Registry;
+
+ #[plugin_registrar]
+ pub fn foo(_reg: &mut Registry) {
+ println!("{}", baz::baz());
+ }
+ "#);
+ let baz = project("baz")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "baz"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "baz"
+ crate_type = ["dylib"]
+ "#)
+ .file("src/lib.rs", "pub fn baz() -> i32 { 1 }");
+ bar.build();
+ baz.build();
+
+ assert_that(foo.cargo_process("build"),
+ execs().with_status(0));
+ assert_that(foo.cargo("doc"),
+ execs().with_status(0));
+}
+
+#[test]
+fn plugin_with_dynamic_native_dependency() {
+ if !is_nightly() { return }
+
+ let build = project("builder")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "builder"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "builder"
+ crate-type = ["dylib"]
+ "#)
+ .file("src/lib.rs", r#"
+ #[no_mangle]
+ pub extern fn foo() {}
+ "#);
+ assert_that(build.cargo_process("build"),
+ execs().with_status(0));
+ let src = build.root().join("target/debug");
+ let lib = fs::read_dir(&src).unwrap().map(|s| s.unwrap().path()).find(|lib| {
+ let lib = lib.file_name().unwrap().to_str().unwrap();
+ lib.starts_with(env::consts::DLL_PREFIX) &&
+ lib.ends_with(env::consts::DLL_SUFFIX)
+ }).unwrap();
+
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/main.rs", r#"
+ #![feature(plugin)]
+ #![plugin(bar)]
+
+ fn main() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ build = 'build.rs'
+
+ [lib]
+ name = "bar"
+ plugin = true
+ "#)
+ .file("bar/build.rs", r#"
+ use std::path::PathBuf;
+ use std::env;
+
+ fn main() {
+ let src = PathBuf::from(env::var("SRC").unwrap());
+ println!("cargo:rustc-flags=-L {}", src.parent().unwrap()
+ .display());
+ }
+ "#)
+ .file("bar/src/lib.rs", r#"
+ #![feature(plugin_registrar, rustc_private)]
+ extern crate rustc_plugin;
+
+ use rustc_plugin::Registry;
+
+ #[cfg_attr(not(target_env = "msvc"), link(name = "builder"))]
+ #[cfg_attr(target_env = "msvc", link(name = "builder.dll"))]
+ extern { fn foo(); }
+
+ #[plugin_registrar]
+ pub fn bar(_reg: &mut Registry) {
+ unsafe { foo() }
+ }
+ "#);
+
+ assert_that(foo.cargo_process("build").env("SRC", &lib).arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn plugin_integration() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+
+ [lib]
+ name = "foo"
+ plugin = true
+ doctest = false
+ "#)
+ .file("build.rs", "fn main() {}")
+ .file("src/lib.rs", "")
+ .file("tests/it_works.rs", "");
+
+ assert_that(p.cargo_process("test").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn doctest_a_plugin() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = { path = "bar" }
+ "#)
+ .file("src/lib.rs", r#"
+ #[macro_use]
+ extern crate bar;
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "bar"
+ plugin = true
+ "#)
+ .file("bar/src/lib.rs", r#"
+ pub fn bar() {}
+ "#);
+
+ assert_that(p.cargo_process("test").arg("-v"),
+ execs().with_status(0));
+}
+
+// See #1515
+#[test]
+fn native_plugin_dependency_with_custom_ar_linker() {
+ let target = rustc_host();
+
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo"
+ plugin = true
+ "#)
+ .file("src/lib.rs", "");
+
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "bar"
+
+ [dependencies.foo]
+ path = "../foo"
+ "#)
+ .file("src/lib", "")
+ .file(".cargo/config", &format!(r#"
+ [target.{}]
+ ar = "nonexistent-ar"
+ linker = "nonexistent-linker"
+ "#, target));
+
+ foo.build();
+ assert_that(bar.cargo_process("build").arg("--verbose"),
+ execs().with_stderr_contains("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc [..] -C ar=nonexistent-ar -C linker=nonexistent-linker [..]`
+[ERROR] could not exec the linker [..]
+"));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::env;
+use std::path::MAIN_SEPARATOR as SEP;
+
+use cargotest::support::{project, execs};
+use hamcrest::assert_that;
+
+#[test]
+fn profile_overrides() {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "test"
+ version = "0.0.0"
+ authors = []
+
+ [profile.dev]
+ opt-level = 1
+ debug = false
+ rpath = true
+ "#)
+ .file("src/lib.rs", "");
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] test v0.0.0 ({url})
+[RUNNING] `rustc src{sep}lib.rs --crate-name test --crate-type lib \
+ -C opt-level=1 \
+ -C debug-assertions=on \
+ -C rpath \
+ --out-dir {dir}{sep}target{sep}debug \
+ --emit=dep-info,link \
+ -L dependency={dir}{sep}target{sep}debug \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps`
+", sep = SEP,
+dir = p.root().display(),
+url = p.url(),
+)));
+}
+
+#[test]
+fn top_level_overrides_deps() {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "test"
+ version = "0.0.0"
+ authors = []
+
+ [profile.release]
+ opt-level = 1
+ debug = true
+
+ [dependencies.foo]
+ path = "foo"
+ "#)
+ .file("src/lib.rs", "")
+ .file("foo/Cargo.toml", r#"
+ [package]
+
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+
+ [profile.release]
+ opt-level = 0
+ debug = false
+
+ [lib]
+ name = "foo"
+ crate_type = ["dylib", "rlib"]
+ "#)
+ .file("foo/src/lib.rs", "");
+ assert_that(p.cargo_process("build").arg("-v").arg("--release"),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] foo v0.0.0 ({url}/foo)
+[RUNNING] `rustc foo{sep}src{sep}lib.rs --crate-name foo \
+ --crate-type dylib --crate-type rlib -C prefer-dynamic \
+ -C opt-level=1 \
+ -g \
+ -C metadata=[..] \
+ -C extra-filename=-[..] \
+ --out-dir {dir}{sep}target{sep}release{sep}deps \
+ --emit=dep-info,link \
+ -L dependency={dir}{sep}target{sep}release{sep}deps \
+ -L dependency={dir}{sep}target{sep}release{sep}deps`
+[COMPILING] test v0.0.0 ({url})
+[RUNNING] `rustc src{sep}lib.rs --crate-name test --crate-type lib \
+ -C opt-level=1 \
+ -g \
+ --out-dir {dir}{sep}target{sep}release \
+ --emit=dep-info,link \
+ -L dependency={dir}{sep}target{sep}release \
+ -L dependency={dir}{sep}target{sep}release{sep}deps \
+ --extern foo={dir}{sep}target{sep}release{sep}deps{sep}\
+ {prefix}foo-[..]{suffix} \
+ --extern foo={dir}{sep}target{sep}release{sep}deps{sep}libfoo-[..].rlib`
+",
+ dir = p.root().display(),
+ url = p.url(),
+ sep = SEP,
+ prefix = env::consts::DLL_PREFIX,
+ suffix = env::consts::DLL_SUFFIX)));
+}
--- /dev/null
+extern crate cargotest;
+extern crate flate2;
+extern crate hamcrest;
+extern crate tar;
+extern crate url;
+
+use std::io::prelude::*;
+use std::fs::{self, File};
+use std::io::SeekFrom;
+use std::path::PathBuf;
+
+use cargotest::support::git::repo;
+use cargotest::support::paths;
+use cargotest::support::{project, execs};
+use flate2::read::GzDecoder;
+use hamcrest::assert_that;
+use tar::Archive;
+use url::Url;
+
+fn registry_path() -> PathBuf { paths::root().join("registry") }
+fn registry() -> Url { Url::from_file_path(&*registry_path()).ok().unwrap() }
+fn upload_path() -> PathBuf { paths::root().join("upload") }
+fn upload() -> Url { Url::from_file_path(&*upload_path()).ok().unwrap() }
+
+fn setup() {
+ let config = paths::root().join(".cargo/config");
+ fs::create_dir_all(config.parent().unwrap()).unwrap();
+ File::create(&config).unwrap().write_all(&format!(r#"
+ [registry]
+ index = "{reg}"
+ token = "api-token"
+ "#, reg = registry()).as_bytes()).unwrap();
+ fs::create_dir_all(&upload_path().join("api/v1/crates")).unwrap();
+
+ repo(®istry_path())
+ .file("config.json", &format!(r#"{{
+ "dl": "{0}",
+ "api": "{0}"
+ }}"#, upload()))
+ .build();
+}
+
+#[test]
+fn simple() {
+ setup();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "foo"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("publish").arg("--no-verify"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] registry `{reg}`
+[WARNING] manifest has no documentation, [..]
+[PACKAGING] foo v0.0.1 ({dir})
+[UPLOADING] foo v0.0.1 ({dir})
+",
+ dir = p.url(),
+ reg = registry())));
+
+ let mut f = File::open(&upload_path().join("api/v1/crates/new")).unwrap();
+ // Skip the metadata payload and the size of the tarball
+ let mut sz = [0; 4];
+ assert_eq!(f.read(&mut sz).unwrap(), 4);
+ let sz = ((sz[0] as u32) << 0) |
+ ((sz[1] as u32) << 8) |
+ ((sz[2] as u32) << 16) |
+ ((sz[3] as u32) << 24);
+ f.seek(SeekFrom::Current(sz as i64 + 4)).unwrap();
+
+ // Verify the tarball
+ let mut rdr = GzDecoder::new(f).unwrap();
+ assert_eq!(rdr.header().filename().unwrap(), "foo-0.0.1.crate".as_bytes());
+ let mut contents = Vec::new();
+ rdr.read_to_end(&mut contents).unwrap();
+ let mut ar = Archive::new(&contents[..]);
+ for file in ar.entries().unwrap() {
+ let file = file.unwrap();
+ let fname = file.header().path_bytes();
+ let fname = &*fname;
+ assert!(fname == b"foo-0.0.1/Cargo.toml" ||
+ fname == b"foo-0.0.1/src/main.rs",
+ "unexpected filename: {:?}", file.header().path());
+ }
+}
+
+#[test]
+fn git_deps() {
+ setup();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "foo"
+
+ [dependencies.foo]
+ git = "git://path/to/nowhere"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("publish").arg("-v").arg("--no-verify"),
+ execs().with_status(101).with_stderr("\
+[UPDATING] registry [..]
+[ERROR] all dependencies must come from the same source.
+dependency `foo` comes from git://path/to/nowhere instead
+"));
+}
+
+#[test]
+fn path_dependency_no_version() {
+ setup();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "foo"
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "");
+
+ assert_that(p.cargo_process("publish"),
+ execs().with_status(101).with_stderr("\
+[UPDATING] registry [..]
+[ERROR] all path dependencies must have a version specified when publishing.
+dependency `bar` does not specify a version
+"));
+}
+
+#[test]
+fn unpublishable_crate() {
+ setup();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "foo"
+ publish = false
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("publish"),
+ execs().with_status(101).with_stderr("\
+[ERROR] some crates cannot be published.
+`foo` is marked as unpublishable
+"));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use cargotest::support::{project, execs, main_file, basic_bin_manifest};
+use hamcrest::{assert_that};
+
+fn remove_all_whitespace(s: &str) -> String {
+ s.split_whitespace().collect()
+}
+
+fn read_manifest_output() -> String {
+ remove_all_whitespace(r#"
+{
+ "name":"foo",
+ "version":"0.5.0",
+ "id":"foo[..]0.5.0[..](path+file://[..]/foo)",
+ "source":null,
+ "dependencies":[],
+ "targets":[{
+ "kind":["bin"],
+ "name":"foo",
+ "src_path":"src[..]foo.rs"
+ }],
+ "features":{},
+ "manifest_path":"[..]Cargo.toml"
+}"#)
+}
+
+#[test]
+fn cargo_read_manifest_path_to_cargo_toml_relative() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("read-manifest")
+ .arg("--manifest-path").arg("foo/Cargo.toml")
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(0)
+ .with_stdout(read_manifest_output()));
+}
+
+#[test]
+fn cargo_read_manifest_path_to_cargo_toml_absolute() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("read-manifest")
+ .arg("--manifest-path").arg(p.root().join("Cargo.toml"))
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(0)
+ .with_stdout(read_manifest_output()));
+}
+
+#[test]
+fn cargo_read_manifest_path_to_cargo_toml_parent_relative() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("read-manifest")
+ .arg("--manifest-path").arg("foo")
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(101)
+ .with_stderr("[ERROR] the manifest-path must be \
+ a path to a Cargo.toml file"));
+}
+
+#[test]
+fn cargo_read_manifest_path_to_cargo_toml_parent_absolute() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("read-manifest")
+ .arg("--manifest-path").arg(p.root())
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(101)
+ .with_stderr("[ERROR] the manifest-path must be \
+ a path to a Cargo.toml file"));
+}
+
+#[test]
+fn cargo_read_manifest_cwd() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("read-manifest")
+ .cwd(p.root()),
+ execs().with_status(0)
+ .with_stdout(read_manifest_output()));
+}
--- /dev/null
+#[macro_use]
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::fs::{self, File};
+use std::io::prelude::*;
+
+use cargotest::cargo_process;
+use cargotest::support::git;
+use cargotest::support::paths::{self, CargoPathExt};
+use cargotest::support::registry::{self, Package};
+use cargotest::support::{project, execs};
+use hamcrest::assert_that;
+
+#[test]
+fn simple() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = ">= 0.0.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ Package::new("bar", "0.0.1").publish();
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] registry `{reg}`
+[DOWNLOADING] bar v0.0.1 (registry file://[..])
+[COMPILING] bar v0.0.1 (registry file://[..])
+[COMPILING] foo v0.0.1 ({dir})
+",
+ dir = p.url(),
+ reg = registry::registry())));
+
+ // Don't download a second time
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] registry `{reg}`
+[..] bar v0.0.1 (registry file://[..])
+[..] foo v0.0.1 ({dir})
+",
+ dir = p.url(),
+ reg = registry::registry())));
+}
+
+#[test]
+fn deps() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = ">= 0.0.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ Package::new("baz", "0.0.1").publish();
+ Package::new("bar", "0.0.1").dep("baz", "*").publish();
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] registry `{reg}`
+[DOWNLOADING] [..] v0.0.1 (registry file://[..])
+[DOWNLOADING] [..] v0.0.1 (registry file://[..])
+[COMPILING] baz v0.0.1 (registry file://[..])
+[COMPILING] bar v0.0.1 (registry file://[..])
+[COMPILING] foo v0.0.1 ({dir})
+",
+ dir = p.url(),
+ reg = registry::registry())));
+}
+
+#[test]
+fn nonexistent() {
+ Package::new("init", "0.0.1").publish();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ nonexistent = ">= 0.0.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+[UPDATING] registry [..]
+[ERROR] no matching package named `nonexistent` found (required by `foo`)
+location searched: registry file://[..]
+version required: >= 0.0.0
+"));
+}
+
+#[test]
+fn wrong_version() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ foo = ">= 1.0.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ Package::new("foo", "0.0.1").publish();
+ Package::new("foo", "0.0.2").publish();
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr_contains("\
+[ERROR] no matching package named `foo` found (required by `foo`)
+location searched: registry file://[..]
+version required: >= 1.0.0
+versions found: 0.0.2, 0.0.1
+"));
+
+ Package::new("foo", "0.0.3").publish();
+ Package::new("foo", "0.0.4").publish();
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr_contains("\
+[ERROR] no matching package named `foo` found (required by `foo`)
+location searched: registry file://[..]
+version required: >= 1.0.0
+versions found: 0.0.4, 0.0.3, 0.0.2, ...
+"));
+}
+
+#[test]
+fn bad_cksum() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bad-cksum = ">= 0.0.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ let pkg = Package::new("bad-cksum", "0.0.1");
+ pkg.publish();
+ File::create(&pkg.archive_dst()).unwrap();
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(101).with_stderr("\
+[UPDATING] registry [..]
+[DOWNLOADING] bad-cksum [..]
+[ERROR] unable to get packages from source
+
+Caused by:
+ failed to download package `bad-cksum v0.0.1 (registry file://[..])` from [..]
+
+Caused by:
+ failed to verify the checksum of `bad-cksum v0.0.1 (registry file://[..])`
+"));
+}
+
+#[test]
+fn update_registry() {
+ Package::new("init", "0.0.1").publish();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ notyet = ">= 0.0.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr_contains("\
+[ERROR] no matching package named `notyet` found (required by `foo`)
+location searched: registry file://[..]
+version required: >= 0.0.0
+"));
+
+ Package::new("notyet", "0.0.1").publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] registry `{reg}`
+[DOWNLOADING] notyet v0.0.1 (registry file://[..])
+[COMPILING] notyet v0.0.1 (registry file://[..])
+[COMPILING] foo v0.0.1 ({dir})
+",
+ dir = p.url(),
+ reg = registry::registry())));
+}
+
+#[test]
+fn package_with_path_deps() {
+ Package::new("init", "0.0.1").publish();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "foo"
+ repository = "bar"
+
+ [dependencies.notyet]
+ version = "0.0.1"
+ path = "notyet"
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("notyet/Cargo.toml", r#"
+ [package]
+ name = "notyet"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("notyet/src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo("package").arg("-v"),
+ execs().with_status(101).with_stderr_contains("\
+[ERROR] failed to verify package tarball
+
+Caused by:
+ no matching package named `notyet` found (required by `foo`)
+location searched: registry file://[..]
+version required: ^0.0.1
+"));
+
+ Package::new("notyet", "0.0.1").publish();
+
+ assert_that(p.cargo("package"),
+ execs().with_status(0).with_stderr(format!("\
+[PACKAGING] foo v0.0.1 ({dir})
+[VERIFYING] foo v0.0.1 ({dir})
+[UPDATING] registry `[..]`
+[DOWNLOADING] notyet v0.0.1 (registry file://[..])
+[COMPILING] notyet v0.0.1 (registry file://[..])
+[COMPILING] foo v0.0.1 ({dir}[..])
+", dir = p.url())));
+}
+
+#[test]
+fn lockfile_locks() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "*"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("bar", "0.0.1").publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] registry `[..]`
+[DOWNLOADING] bar v0.0.1 (registry file://[..])
+[COMPILING] bar v0.0.1 (registry file://[..])
+[COMPILING] foo v0.0.1 ({dir})
+",
+ dir = p.url())));
+
+ p.root().move_into_the_past();
+ Package::new("bar", "0.0.2").publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stdout(""));
+}
+
+#[test]
+fn lockfile_locks_transitively() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "*"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("baz", "0.0.1").publish();
+ Package::new("bar", "0.0.1").dep("baz", "*").publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] registry `[..]`
+[DOWNLOADING] [..] v0.0.1 (registry file://[..])
+[DOWNLOADING] [..] v0.0.1 (registry file://[..])
+[COMPILING] baz v0.0.1 (registry file://[..])
+[COMPILING] bar v0.0.1 (registry file://[..])
+[COMPILING] foo v0.0.1 ({dir})
+",
+ dir = p.url())));
+
+ p.root().move_into_the_past();
+ Package::new("baz", "0.0.2").publish();
+ Package::new("bar", "0.0.2").dep("baz", "*").publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stdout(""));
+}
+
+#[test]
+fn yanks_are_not_used() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "*"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("baz", "0.0.1").publish();
+ Package::new("baz", "0.0.2").yanked(true).publish();
+ Package::new("bar", "0.0.1").dep("baz", "*").publish();
+ Package::new("bar", "0.0.2").dep("baz", "*").yanked(true).publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] registry `[..]`
+[DOWNLOADING] [..] v0.0.1 (registry file://[..])
+[DOWNLOADING] [..] v0.0.1 (registry file://[..])
+[COMPILING] baz v0.0.1 (registry file://[..])
+[COMPILING] bar v0.0.1 (registry file://[..])
+[COMPILING] foo v0.0.1 ({dir})
+",
+ dir = p.url())));
+}
+
+#[test]
+fn relying_on_a_yank_is_bad() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "*"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("baz", "0.0.1").publish();
+ Package::new("baz", "0.0.2").yanked(true).publish();
+ Package::new("bar", "0.0.1").dep("baz", "=0.0.2").publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(101).with_stderr_contains("\
+[ERROR] no matching package named `baz` found (required by `bar`)
+location searched: registry file://[..]
+version required: = 0.0.2
+versions found: 0.0.1
+"));
+}
+
+#[test]
+fn yanks_in_lockfiles_are_ok() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "*"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("bar", "0.0.1").publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+
+ fs::remove_dir_all(®istry::registry_path().join("3")).unwrap();
+
+ Package::new("bar", "0.0.1").yanked(true).publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stdout(""));
+
+ assert_that(p.cargo("update"),
+ execs().with_status(101).with_stderr_contains("\
+[ERROR] no matching package named `bar` found (required by `foo`)
+location searched: registry file://[..]
+version required: *
+"));
+}
+
+#[test]
+fn update_with_lockfile_if_packages_missing() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "*"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("bar", "0.0.1").publish();
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+ p.root().move_into_the_past();
+
+ paths::home().join(".cargo/registry").rm_rf();
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry `[..]`
+[DOWNLOADING] bar v0.0.1 (registry file://[..])
+"));
+}
+
+#[test]
+fn update_lockfile() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "*"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ println!("0.0.1");
+ Package::new("bar", "0.0.1").publish();
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+
+ Package::new("bar", "0.0.2").publish();
+ Package::new("bar", "0.0.3").publish();
+ paths::home().join(".cargo/registry").rm_rf();
+ println!("0.0.2 update");
+ assert_that(p.cargo("update")
+ .arg("-p").arg("bar").arg("--precise").arg("0.0.2"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry `[..]`
+[UPDATING] bar v0.0.1 (registry file://[..]) -> v0.0.2
+"));
+
+ println!("0.0.2 build");
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[DOWNLOADING] [..] v0.0.2 (registry file://[..])
+[COMPILING] bar v0.0.2 (registry file://[..])
+[COMPILING] foo v0.0.1 ({dir})
+",
+ dir = p.url())));
+
+ println!("0.0.3 update");
+ assert_that(p.cargo("update")
+ .arg("-p").arg("bar"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry `[..]`
+[UPDATING] bar v0.0.2 (registry file://[..]) -> v0.0.3
+"));
+
+ println!("0.0.3 build");
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[DOWNLOADING] [..] v0.0.3 (registry file://[..])
+[COMPILING] bar v0.0.3 (registry file://[..])
+[COMPILING] foo v0.0.1 ({dir})
+",
+ dir = p.url())));
+
+ println!("new dependencies update");
+ Package::new("bar", "0.0.4").dep("spam", "0.2.5").publish();
+ Package::new("spam", "0.2.5").publish();
+ assert_that(p.cargo("update")
+ .arg("-p").arg("bar"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry `[..]`
+[UPDATING] bar v0.0.3 (registry file://[..]) -> v0.0.4
+[ADDING] spam v0.2.5 (registry file://[..])
+"));
+
+ println!("new dependencies update");
+ Package::new("bar", "0.0.5").publish();
+ assert_that(p.cargo("update")
+ .arg("-p").arg("bar"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry `[..]`
+[UPDATING] bar v0.0.4 (registry file://[..]) -> v0.0.5
+[REMOVING] spam v0.2.5 (registry file://[..])
+"));
+}
+
+#[test]
+fn dev_dependency_not_used() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "*"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("baz", "0.0.1").publish();
+ Package::new("bar", "0.0.1").dev_dep("baz", "*").publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] registry `[..]`
+[DOWNLOADING] [..] v0.0.1 (registry file://[..])
+[COMPILING] bar v0.0.1 (registry file://[..])
+[COMPILING] foo v0.0.1 ({dir})
+",
+ dir = p.url())));
+}
+
+#[test]
+fn login_with_no_cargo_dir() {
+ let home = paths::home().join("new-home");
+ fs::create_dir(&home).unwrap();
+ assert_that(cargo_process().arg("login").arg("foo").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn bad_license_file() {
+ Package::new("foo", "1.0.0").publish();
+ let p = project("all")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license-file = "foo"
+ description = "bar"
+ repository = "baz"
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#);
+ assert_that(p.cargo_process("publish").arg("-v"),
+ execs().with_status(101)
+ .with_stderr_contains("\
+[ERROR] the license file `foo` does not exist"));
+}
+
+#[test]
+fn updating_a_dep() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.a]
+ path = "a"
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("a/Cargo.toml", r#"
+ [project]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "*"
+ "#)
+ .file("a/src/lib.rs", "");
+ p.build();
+
+ Package::new("bar", "0.0.1").publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] registry `[..]`
+[DOWNLOADING] bar v0.0.1 (registry file://[..])
+[COMPILING] bar v0.0.1 (registry file://[..])
+[COMPILING] a v0.0.1 ({dir}/a)
+[COMPILING] foo v0.0.1 ({dir})
+",
+ dir = p.url())));
+
+ t!(File::create(&p.root().join("a/Cargo.toml"))).write_all(br#"
+ [project]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "0.1.0"
+ "#).unwrap();
+ Package::new("bar", "0.1.0").publish();
+
+ println!("second");
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] registry `[..]`
+[DOWNLOADING] bar v0.1.0 (registry file://[..])
+[COMPILING] bar v0.1.0 (registry file://[..])
+[COMPILING] a v0.0.1 ({dir}/a)
+[COMPILING] foo v0.0.1 ({dir})
+",
+ dir = p.url())));
+}
+
+#[test]
+fn git_and_registry_dep() {
+ let b = git::repo(&paths::root().join("b"))
+ .file("Cargo.toml", r#"
+ [project]
+ name = "b"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ a = "0.0.1"
+ "#)
+ .file("src/lib.rs", "");
+ b.build();
+ let p = project("foo")
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ a = "0.0.1"
+
+ [dependencies.b]
+ git = '{}'
+ "#, b.url()))
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("a", "0.0.1").publish();
+
+ p.root().move_into_the_past();
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] [..]
+[UPDATING] [..]
+[DOWNLOADING] a v0.0.1 (registry file://[..])
+[COMPILING] a v0.0.1 (registry [..])
+[COMPILING] b v0.0.1 ([..])
+[COMPILING] foo v0.0.1 ({dir})
+",
+ dir = p.url())));
+ p.root().move_into_the_past();
+
+ println!("second");
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stdout(""));
+}
+
+#[test]
+fn update_publish_then_update() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ a = "0.1.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("a", "0.1.0").publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+
+ Package::new("a", "0.1.1").publish();
+
+ let lock = p.root().join("Cargo.lock");
+ let mut s = String::new();
+ File::open(&lock).unwrap().read_to_string(&mut s).unwrap();
+ File::create(&lock).unwrap()
+ .write_all(s.replace("0.1.0", "0.1.1").as_bytes()).unwrap();
+ println!("second");
+
+ fs::remove_dir_all(&p.root().join("target")).unwrap();
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr(&format!("\
+[UPDATING] [..]
+[DOWNLOADING] a v0.1.1 (registry file://[..])
+[COMPILING] a v0.1.1 (registry [..])
+[COMPILING] foo v0.5.0 ({dir})
+",
+ dir = p.url())));
+
+}
+
+#[test]
+fn fetch_downloads() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ a = "0.1.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("a", "0.1.0").publish();
+
+ assert_that(p.cargo("fetch"),
+ execs().with_status(0)
+ .with_stderr("\
+[UPDATING] registry `[..]`
+[DOWNLOADING] a v0.1.0 (registry [..])
+"));
+}
+
+#[test]
+fn update_transitive_dependency() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ a = "0.1.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("a", "0.1.0").dep("b", "*").publish();
+ Package::new("b", "0.1.0").publish();
+
+ assert_that(p.cargo("fetch"),
+ execs().with_status(0));
+
+ Package::new("b", "0.1.1").publish();
+
+ assert_that(p.cargo("update").arg("-pb"),
+ execs().with_status(0)
+ .with_stderr("\
+[UPDATING] registry `[..]`
+[UPDATING] b v0.1.0 (registry [..]) -> v0.1.1
+"));
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0)
+ .with_stderr("\
+[DOWNLOADING] b v0.1.1 (registry file://[..])
+[COMPILING] b v0.1.1 (registry [..])
+[COMPILING] a v0.1.0 (registry [..])
+[COMPILING] foo v0.5.0 ([..])
+"));
+}
+
+#[test]
+fn update_backtracking_ok() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ webdriver = "0.1"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("webdriver", "0.1.0").dep("hyper", "0.6").publish();
+ Package::new("hyper", "0.6.5").dep("openssl", "0.1")
+ .dep("cookie", "0.1")
+ .publish();
+ Package::new("cookie", "0.1.0").dep("openssl", "0.1").publish();
+ Package::new("openssl", "0.1.0").publish();
+
+ assert_that(p.cargo("generate-lockfile"),
+ execs().with_status(0));
+
+ Package::new("openssl", "0.1.1").publish();
+ Package::new("hyper", "0.6.6").dep("openssl", "0.1.1")
+ .dep("cookie", "0.1.0")
+ .publish();
+
+ assert_that(p.cargo("update").arg("-p").arg("hyper"),
+ execs().with_status(0)
+ .with_stderr("\
+[UPDATING] registry `[..]`
+"));
+}
+
+#[test]
+fn update_multiple_packages() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ a = "*"
+ b = "*"
+ c = "*"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("a", "0.1.0").publish();
+ Package::new("b", "0.1.0").publish();
+ Package::new("c", "0.1.0").publish();
+
+ assert_that(p.cargo("fetch"),
+ execs().with_status(0));
+
+ Package::new("a", "0.1.1").publish();
+ Package::new("b", "0.1.1").publish();
+ Package::new("c", "0.1.1").publish();
+
+ assert_that(p.cargo("update").arg("-pa").arg("-pb"),
+ execs().with_status(0)
+ .with_stderr("\
+[UPDATING] registry `[..]`
+[UPDATING] a v0.1.0 (registry [..]) -> v0.1.1
+[UPDATING] b v0.1.0 (registry [..]) -> v0.1.1
+"));
+
+ assert_that(p.cargo("update").arg("-pb").arg("-pc"),
+ execs().with_status(0)
+ .with_stderr("\
+[UPDATING] registry `[..]`
+[UPDATING] c v0.1.0 (registry [..]) -> v0.1.1
+"));
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0)
+ .with_stderr_contains("\
+[DOWNLOADING] a v0.1.1 (registry file://[..])")
+ .with_stderr_contains("\
+[DOWNLOADING] b v0.1.1 (registry file://[..])")
+ .with_stderr_contains("\
+[DOWNLOADING] c v0.1.1 (registry file://[..])")
+ .with_stderr_contains("\
+[COMPILING] a v0.1.1 (registry [..])")
+ .with_stderr_contains("\
+[COMPILING] b v0.1.1 (registry [..])")
+ .with_stderr_contains("\
+[COMPILING] c v0.1.1 (registry [..])")
+ .with_stderr_contains("\
+[COMPILING] foo v0.5.0 ([..])"));
+}
+
+#[test]
+fn bundled_crate_in_registry() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ bar = "0.1"
+ baz = "0.1"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("bar", "0.1.0").publish();
+ Package::new("baz", "0.1.0")
+ .dep("bar", "0.1.0")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "baz"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ bar = { path = "bar", version = "0.1.0" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "")
+ .publish();
+
+ assert_that(p.cargo("run"), execs().with_status(0));
+}
+
+#[test]
+fn update_same_prefix_oh_my_how_was_this_a_bug() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "ugh"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ foo = "0.1"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("foobar", "0.2.0").publish();
+ Package::new("foo", "0.1.0")
+ .dep("foobar", "0.2.0")
+ .publish();
+
+ assert_that(p.cargo("generate-lockfile"), execs().with_status(0));
+ assert_that(p.cargo("update").arg("-pfoobar").arg("--precise=0.2.0"),
+ execs().with_status(0));
+}
+
+#[test]
+fn use_semver() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "bar"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ foo = "1.2.3-alpha.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("foo", "1.2.3-alpha.0").publish();
+
+ assert_that(p.cargo("build"), execs().with_status(0));
+}
+
+#[test]
+fn only_download_relevant() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "bar"
+ version = "0.5.0"
+ authors = []
+
+ [target.foo.dependencies]
+ foo = "*"
+ [dev-dependencies]
+ bar = "*"
+ [dependencies]
+ baz = "*"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("foo", "0.1.0").publish();
+ Package::new("bar", "0.1.0").publish();
+ Package::new("baz", "0.1.0").publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr("\
+[UPDATING] registry `[..]`
+[DOWNLOADING] baz v0.1.0 ([..])
+[COMPILING] baz v0.1.0 ([..])
+[COMPILING] bar v0.5.0 ([..])
+"));
+}
+
+#[test]
+fn resolve_and_backtracking() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "bar"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ foo = "*"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("foo", "0.1.1")
+ .feature_dep("bar", "0.1", &["a", "b"])
+ .publish();
+ Package::new("foo", "0.1.0").publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::path::MAIN_SEPARATOR as SEP;
+
+use cargotest::support::{project, execs, path2url};
+use hamcrest::{assert_that, existing_file};
+
+#[test]
+fn simple() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() { println!("hello"); }
+ "#);
+
+ assert_that(p.cargo_process("run"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] `target{sep}debug{sep}foo[..]`", dir = path2url(p.root()), sep = SEP))
+ .with_stdout("\
+hello
+"));
+ assert_that(&p.bin("foo"), existing_file());
+}
+
+#[test]
+fn simple_quiet() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() { println!("hello"); }
+ "#);
+
+ assert_that(p.cargo_process("run").arg("-q"),
+ execs().with_status(0).with_stdout("\
+hello
+")
+ );
+}
+
+#[test]
+fn simple_quiet_and_verbose() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() { println!("hello"); }
+ "#);
+
+ assert_that(p.cargo_process("run").arg("-q").arg("-v"),
+ execs().with_status(101).with_stderr("\
+[ERROR] cannot set both --verbose and --quiet
+"));
+}
+
+#[test]
+fn quiet_and_verbose_config() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file(".cargo/config", r#"
+ [term]
+ verbose = true
+ "#)
+ .file("src/main.rs", r#"
+ fn main() { println!("hello"); }
+ "#);
+
+ assert_that(p.cargo_process("run").arg("-q"),
+ execs().with_status(0));
+}
+
+#[test]
+fn simple_with_args() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {
+ assert_eq!(std::env::args().nth(1).unwrap(), "hello");
+ assert_eq!(std::env::args().nth(2).unwrap(), "world");
+ }
+ "#);
+
+ assert_that(p.cargo_process("run").arg("hello").arg("world"),
+ execs().with_status(0));
+}
+
+#[test]
+fn exit_code() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() { std::process::exit(2); }
+ "#);
+
+ assert_that(p.cargo_process("run"),
+ execs().with_status(2)
+ .with_stderr("\
+[COMPILING] foo v0.0.1 (file[..])
+[RUNNING] `target[..]`
+[ERROR] Process didn't exit successfully: `target[..]foo[..]` (exit code: 2)
+"));
+}
+
+#[test]
+fn exit_code_verbose() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() { std::process::exit(2); }
+ "#);
+
+ assert_that(p.cargo_process("run").arg("-v"),
+ execs().with_status(2)
+ .with_stderr("\
+[COMPILING] foo v0.0.1 (file[..])
+[RUNNING] `rustc [..]`
+[RUNNING] `target[..]`
+[ERROR] Process didn't exit successfully: `target[..]foo[..]` (exit code: 2)
+"));
+}
+
+#[test]
+fn no_main_file() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("run"),
+ execs().with_status(101)
+ .with_stderr("[ERROR] a bin target must be available \
+ for `cargo run`\n"));
+}
+
+#[test]
+fn too_many_bins() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/bin/a.rs", "")
+ .file("src/bin/b.rs", "");
+
+ assert_that(p.cargo_process("run"),
+ execs().with_status(101)
+ .with_stderr("[ERROR] `cargo run` requires that a project only \
+ have one executable; use the `--bin` option \
+ to specify which one to run\n"));
+}
+
+#[test]
+fn specify_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/bin/a.rs", r#"
+ extern crate foo;
+ fn main() { println!("hello a.rs"); }
+ "#)
+ .file("src/bin/b.rs", r#"
+ extern crate foo;
+ fn main() { println!("hello b.rs"); }
+ "#);
+
+ assert_that(p.cargo_process("run").arg("--bin").arg("a").arg("-v"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] `rustc src[..]lib.rs [..]`
+[RUNNING] `rustc src[..]a.rs [..]`
+[RUNNING] `target{sep}debug{sep}a[..]`", dir = path2url(p.root()), sep = SEP))
+ .with_stdout("\
+hello a.rs
+"));
+
+ assert_that(p.cargo("run").arg("--bin").arg("b").arg("-v"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc src[..]b.rs [..]`
+[RUNNING] `target{sep}debug{sep}b[..]`", sep = SEP))
+ .with_stdout("\
+hello b.rs
+"));
+}
+
+#[test]
+fn run_example() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("examples/a.rs", r#"
+ fn main() { println!("example"); }
+ "#)
+ .file("src/bin/a.rs", r#"
+ fn main() { println!("bin"); }
+ "#);
+
+ assert_that(p.cargo_process("run").arg("--example").arg("a"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] `target{sep}debug{sep}examples{sep}a[..]`", dir = path2url(p.root()), sep = SEP))
+ .with_stdout("\
+example
+"));
+}
+
+#[test]
+fn run_with_filename() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/bin/a.rs", r#"
+ extern crate foo;
+ fn main() { println!("hello a.rs"); }
+ "#)
+ .file("examples/a.rs", r#"
+ fn main() { println!("example"); }
+ "#);
+
+ assert_that(p.cargo_process("run").arg("--bin").arg("bin.rs"),
+ execs().with_status(101).with_stderr("\
+[ERROR] no bin target named `bin.rs`"));
+
+ assert_that(p.cargo_process("run").arg("--bin").arg("a.rs"),
+ execs().with_status(101).with_stderr("\
+[ERROR] no bin target named `a.rs`
+
+Did you mean `a`?"));
+
+ assert_that(p.cargo_process("run").arg("--example").arg("example.rs"),
+ execs().with_status(101).with_stderr("\
+[ERROR] no example target named `example.rs`"));
+
+ assert_that(p.cargo_process("run").arg("--example").arg("a.rs"),
+ execs().with_status(101).with_stderr("\
+[ERROR] no example target named `a.rs`
+
+Did you mean `a`?"));
+}
+
+#[test]
+fn either_name_or_example() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/bin/a.rs", r#"
+ fn main() { println!("hello a.rs"); }
+ "#)
+ .file("examples/b.rs", r#"
+ fn main() { println!("hello b.rs"); }
+ "#);
+
+ assert_that(p.cargo_process("run").arg("--bin").arg("a").arg("--example").arg("b"),
+ execs().with_status(101)
+ .with_stderr("[ERROR] `cargo run` can run at most one \
+ executable, but multiple were \
+ specified"));
+}
+
+#[test]
+fn one_bin_multiple_examples() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/bin/main.rs", r#"
+ fn main() { println!("hello main.rs"); }
+ "#)
+ .file("examples/a.rs", r#"
+ fn main() { println!("hello a.rs"); }
+ "#)
+ .file("examples/b.rs", r#"
+ fn main() { println!("hello b.rs"); }
+ "#);
+
+ assert_that(p.cargo_process("run"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] `target{sep}debug{sep}main[..]`", dir = path2url(p.root()), sep = SEP))
+ .with_stdout("\
+hello main.rs
+"));
+}
+
+#[test]
+fn example_with_release_flag() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ version = "*"
+ path = "bar"
+ "#)
+ .file("examples/a.rs", r#"
+ extern crate bar;
+
+ fn main() {
+ if cfg!(debug_assertions) {
+ println!("slow1")
+ } else {
+ println!("fast1")
+ }
+ bar::baz();
+ }
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [project]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "bar"
+ "#)
+ .file("bar/src/bar.rs", r#"
+ pub fn baz() {
+ if cfg!(debug_assertions) {
+ println!("slow2")
+ } else {
+ println!("fast2")
+ }
+ }
+ "#);
+
+ assert_that(p.cargo_process("run").arg("-v").arg("--release").arg("--example").arg("a"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] bar v0.0.1 ({url}/bar)
+[RUNNING] `rustc bar{sep}src{sep}bar.rs --crate-name bar --crate-type lib \
+ -C opt-level=3 \
+ -C metadata=[..] \
+ -C extra-filename=[..] \
+ --out-dir {dir}{sep}target{sep}release{sep}deps \
+ --emit=dep-info,link \
+ -L dependency={dir}{sep}target{sep}release{sep}deps \
+ -L dependency={dir}{sep}target{sep}release{sep}deps`
+[COMPILING] foo v0.0.1 ({url})
+[RUNNING] `rustc examples{sep}a.rs --crate-name a --crate-type bin \
+ -C opt-level=3 \
+ --out-dir {dir}{sep}target{sep}release{sep}examples \
+ --emit=dep-info,link \
+ -L dependency={dir}{sep}target{sep}release \
+ -L dependency={dir}{sep}target{sep}release{sep}deps \
+ --extern bar={dir}{sep}target{sep}release{sep}deps{sep}libbar-[..].rlib`
+[RUNNING] `target{sep}release{sep}examples{sep}a[..]`
+",
+ dir = p.root().display(),
+ url = path2url(p.root()),
+ sep = SEP))
+ .with_stdout("\
+fast1
+fast2"));
+
+ assert_that(p.cargo("run").arg("-v").arg("--example").arg("a"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] bar v0.0.1 ({url}/bar)
+[RUNNING] `rustc bar{sep}src{sep}bar.rs --crate-name bar --crate-type lib \
+ -g \
+ -C metadata=[..] \
+ -C extra-filename=[..] \
+ --out-dir {dir}{sep}target{sep}debug{sep}deps \
+ --emit=dep-info,link \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps`
+[COMPILING] foo v0.0.1 ({url})
+[RUNNING] `rustc examples{sep}a.rs --crate-name a --crate-type bin \
+ -g \
+ --out-dir {dir}{sep}target{sep}debug{sep}examples \
+ --emit=dep-info,link \
+ -L dependency={dir}{sep}target{sep}debug \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps \
+ --extern bar={dir}{sep}target{sep}debug{sep}deps{sep}libbar-[..].rlib`
+[RUNNING] `target{sep}debug{sep}examples{sep}a[..]`
+",
+ dir = p.root().display(),
+ url = path2url(p.root()),
+ sep = SEP))
+ .with_stdout("\
+slow1
+slow2"));
+}
+
+#[test]
+fn run_dylib_dep() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/main.rs", r#"
+ extern crate bar;
+ fn main() { bar::bar(); }
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "bar"
+ crate-type = ["dylib"]
+ "#)
+ .file("bar/src/lib.rs", "pub fn bar() {}");
+
+ assert_that(p.cargo_process("run").arg("hello").arg("world"),
+ execs().with_status(0));
+}
+
+#[test]
+fn release_works() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() { if cfg!(debug_assertions) { panic!() } }
+ "#);
+
+ assert_that(p.cargo_process("run").arg("--release"),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] `target{sep}release{sep}foo[..]`
+",
+ dir = path2url(p.root()),
+ sep = SEP)));
+ assert_that(&p.release_bin("foo"), existing_file());
+}
+
+#[test]
+fn run_bin_different_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [[bin]]
+ name = "bar"
+ "#)
+ .file("src/bar.rs", r#"
+ fn main() { }
+ "#);
+
+ assert_that(p.cargo_process("run"), execs().with_status(0));
+}
+
+#[test]
+fn dashes_are_forwarded() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [[bin]]
+ name = "bar"
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {
+ let s: Vec<String> = std::env::args().collect();
+ assert_eq!(s[1], "a");
+ assert_eq!(s[2], "--");
+ assert_eq!(s[3], "b");
+ }
+ "#);
+
+ assert_that(p.cargo_process("run").arg("--").arg("a").arg("--").arg("b"),
+ execs().with_status(0));
+}
+
+#[test]
+fn run_from_executable_folder() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() { println!("hello"); }
+ "#);
+
+ let cwd = p.root().join("target").join("debug");
+ p.cargo_process("build").exec_with_output().unwrap();
+
+ assert_that(p.cargo("run").cwd(cwd),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[RUNNING] `.{sep}foo[..]`", sep = SEP))
+ .with_stdout("\
+hello
+"));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::path::MAIN_SEPARATOR as SEP;
+
+use cargotest::support::{execs, project};
+use hamcrest::assert_that;
+
+const CARGO_RUSTC_ERROR: &'static str =
+"[ERROR] extra arguments to `rustc` can only be passed to one target, consider filtering
+the package by passing e.g. `--lib` or `--bin NAME` to specify a single target";
+
+#[test]
+fn build_lib_for_foo() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("src/lib.rs", r#" "#);
+
+ assert_that(p.cargo_process("rustc").arg("--lib").arg("-v"),
+ execs()
+ .with_status(0)
+ .with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({url})
+[RUNNING] `rustc src{sep}lib.rs --crate-name foo --crate-type lib -g \
+ --out-dir {dir}{sep}target{sep}debug \
+ --emit=dep-info,link \
+ -L dependency={dir}{sep}target{sep}debug \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps`
+", sep = SEP,
+ dir = p.root().display(), url = p.url())));
+}
+
+#[test]
+fn lib() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("src/lib.rs", r#" "#);
+
+ assert_that(p.cargo_process("rustc").arg("--lib").arg("-v")
+ .arg("--").arg("-C").arg("debug-assertions=off"),
+ execs()
+ .with_status(0)
+ .with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({url})
+[RUNNING] `rustc src{sep}lib.rs --crate-name foo --crate-type lib -g \
+ -C debug-assertions=off \
+ --out-dir {dir}{sep}target{sep}debug \
+ --emit=dep-info,link \
+ -L dependency={dir}{sep}target{sep}debug \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps`
+", sep = SEP,
+ dir = p.root().display(), url = p.url())))
+}
+
+#[test]
+fn build_main_and_allow_unstable_options() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("src/lib.rs", r#" "#);
+
+ assert_that(p.cargo_process("rustc").arg("-v").arg("--bin").arg("foo")
+ .arg("--").arg("-C").arg("debug-assertions"),
+ execs()
+ .with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] {name} v{version} ({url})
+[RUNNING] `rustc src{sep}lib.rs --crate-name {name} --crate-type lib -g \
+ --out-dir {dir}{sep}target{sep}debug \
+ --emit=dep-info,link \
+ -L dependency={dir}{sep}target{sep}debug \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps`
+[RUNNING] `rustc src{sep}main.rs --crate-name {name} --crate-type bin -g \
+ -C debug-assertions \
+ --out-dir {dir}{sep}target{sep}debug \
+ --emit=dep-info,link \
+ -L dependency={dir}{sep}target{sep}debug \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps \
+ --extern {name}={dir}{sep}target{sep}debug{sep}lib{name}.rlib`
+", sep = SEP,
+ dir = p.root().display(), url = p.url(),
+ name = "foo", version = "0.0.1")));
+}
+
+#[test]
+fn fails_when_trying_to_build_main_and_lib_with_args() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("src/lib.rs", r#" "#);
+
+ assert_that(p.cargo_process("rustc").arg("-v")
+ .arg("--").arg("-C").arg("debug-assertions"),
+ execs()
+ .with_status(101)
+ .with_stderr(CARGO_RUSTC_ERROR));
+}
+
+#[test]
+fn build_with_args_to_one_of_multiple_binaries() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/bin/foo.rs", r#"
+ fn main() {}
+ "#)
+ .file("src/bin/bar.rs", r#"
+ fn main() {}
+ "#)
+ .file("src/bin/baz.rs", r#"
+ fn main() {}
+ "#)
+ .file("src/lib.rs", r#" "#);
+
+ assert_that(p.cargo_process("rustc").arg("-v").arg("--bin").arg("bar")
+ .arg("--").arg("-C").arg("debug-assertions"),
+ execs()
+ .with_status(0)
+ .with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({url})
+[RUNNING] `rustc src{sep}lib.rs --crate-name foo --crate-type lib -g \
+ --out-dir {dir}{sep}target{sep}debug [..]`
+[RUNNING] `rustc src{sep}bin{sep}bar.rs --crate-name bar --crate-type bin -g \
+ -C debug-assertions [..]`
+", sep = SEP,
+ dir = p.root().display(), url = p.url())));
+}
+
+#[test]
+fn fails_with_args_to_all_binaries() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/bin/foo.rs", r#"
+ fn main() {}
+ "#)
+ .file("src/bin/bar.rs", r#"
+ fn main() {}
+ "#)
+ .file("src/bin/baz.rs", r#"
+ fn main() {}
+ "#)
+ .file("src/lib.rs", r#" "#);
+
+ assert_that(p.cargo_process("rustc").arg("-v")
+ .arg("--").arg("-C").arg("debug-assertions"),
+ execs()
+ .with_status(101)
+ .with_stderr(CARGO_RUSTC_ERROR));
+}
+
+#[test]
+fn build_with_args_to_one_of_multiple_tests() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("tests/foo.rs", r#" "#)
+ .file("tests/bar.rs", r#" "#)
+ .file("tests/baz.rs", r#" "#)
+ .file("src/lib.rs", r#" "#);
+
+ assert_that(p.cargo_process("rustc").arg("-v").arg("--test").arg("bar")
+ .arg("--").arg("-C").arg("debug-assertions"),
+ execs()
+ .with_status(0)
+ .with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({url})
+[RUNNING] `rustc src{sep}lib.rs --crate-name foo --crate-type lib -g \
+ --out-dir {dir}{sep}target{sep}debug [..]`
+[RUNNING] `rustc tests{sep}bar.rs --crate-name bar --crate-type bin -g \
+ -C debug-assertions [..]--test[..]`
+", sep = SEP,
+ dir = p.root().display(), url = p.url())));
+}
+
+#[test]
+fn build_foo_with_bar_dependency() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/main.rs", r#"
+ extern crate bar;
+ fn main() {
+ bar::baz()
+ }
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn baz() {}
+ "#);
+ bar.build();
+
+ assert_that(foo.cargo_process("rustc").arg("-v").arg("--").arg("-C").arg("debug-assertions"),
+ execs()
+ .with_status(0)
+ .with_stderr(format!("\
+[COMPILING] bar v0.1.0 ([..])
+[RUNNING] `[..] -g -C [..]`
+[COMPILING] foo v0.0.1 ({url})
+[RUNNING] `[..] -g -C debug-assertions [..]`
+",
+ url = foo.url())));
+}
+
+#[test]
+fn build_only_bar_dependency() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/main.rs", r#"
+ extern crate bar;
+ fn main() {
+ bar::baz()
+ }
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn baz() {}
+ "#);
+ bar.build();
+
+ assert_that(foo.cargo_process("rustc").arg("-v").arg("-p").arg("bar")
+ .arg("--").arg("-C").arg("debug-assertions"),
+ execs()
+ .with_status(0)
+ .with_stderr("\
+[COMPILING] bar v0.1.0 ([..])
+[RUNNING] `[..]--crate-name bar --crate-type lib [..] -C debug-assertions [..]`
+"));
+}
+
+#[test]
+fn fail_with_multiple_packages() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "../bar"
+
+ [dependencies.baz]
+ path = "../baz"
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#);
+ foo.build();
+
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {
+ if cfg!(flag = "1") { println!("Yeah from bar!"); }
+ }
+ "#);
+ bar.build();
+
+ let baz = project("baz")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "baz"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {
+ if cfg!(flag = "1") { println!("Yeah from baz!"); }
+ }
+ "#);
+ baz.build();
+
+ assert_that(foo.cargo("rustc").arg("-v").arg("-p").arg("bar")
+ .arg("-p").arg("baz"),
+ execs().with_status(1).with_stderr("\
+[ERROR] Invalid arguments.
+
+Usage:
+ cargo rustc [options] [--] [<opts>...]"));
+}
+
+#[test]
+fn rustc_with_other_profile() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dev-dependencies]
+ a = { path = "a" }
+ "#)
+ .file("src/main.rs", r#"
+ #[cfg(test)] extern crate a;
+
+ #[test]
+ fn foo() {}
+ "#)
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "");
+ foo.build();
+
+ assert_that(foo.cargo("rustc").arg("--profile").arg("test"),
+ execs().with_status(0));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::path::MAIN_SEPARATOR as SEP;
+
+use cargotest::support::{execs, project};
+use hamcrest::{assert_that};
+
+#[test]
+fn rustdoc_simple() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#" "#);
+
+ assert_that(p.cargo_process("rustdoc").arg("-v"),
+ execs()
+ .with_status(0)
+ .with_stderr(format!("\
+[DOCUMENTING] foo v0.0.1 ({url})
+[RUNNING] `rustdoc src{sep}lib.rs --crate-name foo \
+ -o {dir}{sep}target{sep}doc \
+ -L dependency={dir}{sep}target{sep}debug \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps`
+", sep = SEP,
+ dir = p.root().display(), url = p.url())));
+}
+
+#[test]
+fn rustdoc_args() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#" "#);
+
+ assert_that(p.cargo_process("rustdoc").arg("-v").arg("--").arg("--no-defaults"),
+ execs()
+ .with_status(0)
+ .with_stderr(format!("\
+[DOCUMENTING] foo v0.0.1 ({url})
+[RUNNING] `rustdoc src{sep}lib.rs --crate-name foo \
+ -o {dir}{sep}target{sep}doc \
+ --no-defaults \
+ -L dependency={dir}{sep}target{sep}debug \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps`
+", sep = SEP,
+ dir = p.root().display(), url = p.url())));
+}
+
+
+
+#[test]
+fn rustdoc_foo_with_bar_dependency() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/lib.rs", r#"
+ extern crate bar;
+ pub fn foo() {}
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn baz() {}
+ "#);
+ bar.build();
+
+ assert_that(foo.cargo_process("rustdoc").arg("-v").arg("--").arg("--no-defaults"),
+ execs()
+ .with_status(0)
+ .with_stderr(format!("\
+[COMPILING] bar v0.0.1 ([..])
+[RUNNING] `rustc [..]bar{sep}src{sep}lib.rs [..]`
+[DOCUMENTING] foo v0.0.1 ({url})
+[RUNNING] `rustdoc src{sep}lib.rs --crate-name foo \
+ -o {dir}{sep}target{sep}doc \
+ --no-defaults \
+ -L dependency={dir}{sep}target{sep}debug \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps \
+ --extern [..]`
+", sep = SEP,
+ dir = foo.root().display(), url = foo.url())));
+}
+
+#[test]
+fn rustdoc_only_bar_dependency() {
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/main.rs", r#"
+ extern crate bar;
+ fn main() {
+ bar::baz()
+ }
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn baz() {}
+ "#);
+ bar.build();
+
+ assert_that(foo.cargo_process("rustdoc").arg("-v").arg("-p").arg("bar")
+ .arg("--").arg("--no-defaults"),
+ execs()
+ .with_status(0)
+ .with_stderr(format!("\
+[DOCUMENTING] bar v0.0.1 ([..])
+[RUNNING] `rustdoc [..]bar{sep}src{sep}lib.rs --crate-name bar \
+ -o {dir}{sep}target{sep}doc \
+ --no-defaults \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps \
+ -L dependency={dir}{sep}target{sep}debug{sep}deps`
+", sep = SEP,
+ dir = foo.root().display())));
+}
+
+
+#[test]
+fn rustdoc_same_name_err() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#)
+ .file("src/lib.rs", r#" "#);
+
+ assert_that(p.cargo_process("rustdoc").arg("-v")
+ .arg("--").arg("--no-defaults"),
+ execs()
+ .with_status(101)
+ .with_stderr("[ERROR] cannot document a package where a library and a \
+ binary have the same name. Consider renaming one \
+ or marking the target as `doc = false`"));
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::io::Write;
+use std::fs::{self, File};
+
+use cargotest::rustc_host;
+use cargotest::support::{project, execs, paths};
+use hamcrest::assert_that;
+
+#[test]
+fn env_rustflags_normal_source() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/bin/a.rs", "fn main() {}")
+ .file("examples/b.rs", "fn main() {}")
+ .file("tests/c.rs", "#[test] fn f() { }")
+ .file("benches/d.rs", r#"
+ #![feature(test)]
+ extern crate test;
+ #[bench] fn run1(_ben: &mut test::Bencher) { }"#);
+ p.build();
+
+ // Use RUSTFLAGS to pass an argument that will generate an error
+ assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
+ .arg("--lib"),
+ execs().with_status(101));
+ assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
+ .arg("--bin=a"),
+ execs().with_status(101));
+ assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
+ .arg("--example=b"),
+ execs().with_status(101));
+ assert_that(p.cargo("test").env("RUSTFLAGS", "-Z bogus"),
+ execs().with_status(101));
+ assert_that(p.cargo("bench").env("RUSTFLAGS", "-Z bogus"),
+ execs().with_status(101));
+}
+
+#[test]
+fn env_rustflags_build_script() {
+ // RUSTFLAGS should be passed to rustc for build scripts
+ // when --target is not specified.
+ // In this test if --cfg foo is passed the build will fail.
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() { }
+ #[cfg(not(foo))]
+ fn main() { }
+ "#);
+ p.build();
+
+ assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+ execs().with_status(0));
+}
+
+#[test]
+fn env_rustflags_build_script_dep() {
+ // RUSTFLAGS should be passed to rustc for build scripts
+ // when --target is not specified.
+ // In this test if --cfg foo is not passed the build will fail.
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ build = "build.rs"
+
+ [build-dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() { }
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", r#"
+ fn bar() { }
+ #[cfg(not(foo))]
+ fn bar() { }
+ "#);
+ foo.build();
+ bar.build();
+
+ assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+ execs().with_status(0));
+}
+
+#[test]
+fn env_rustflags_plugin() {
+ // RUSTFLAGS should be passed to rustc for plugins
+ // when --target is not specified.
+ // In this test if --cfg foo is not passed the build will fail.
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+
+ [lib]
+ name = "foo"
+ plugin = true
+ "#)
+ .file("src/lib.rs", r#"
+ fn main() { }
+ #[cfg(not(foo))]
+ fn main() { }
+ "#);
+ p.build();
+
+ assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+ execs().with_status(0));
+}
+
+#[test]
+fn env_rustflags_plugin_dep() {
+ // RUSTFLAGS should be passed to rustc for plugins
+ // when --target is not specified.
+ // In this test if --cfg foo is not passed the build will fail.
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+
+ [lib]
+ name = "foo"
+ plugin = true
+
+ [dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/lib.rs", r#"
+ fn foo() { }
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+
+ [lib]
+ name = "bar"
+ "#)
+ .file("src/lib.rs", r#"
+ fn bar() { }
+ #[cfg(not(foo))]
+ fn bar() { }
+ "#);
+ foo.build();
+ bar.build();
+
+ assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+ execs().with_status(0));
+}
+
+#[test]
+fn env_rustflags_normal_source_with_target() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/bin/a.rs", "fn main() {}")
+ .file("examples/b.rs", "fn main() {}")
+ .file("tests/c.rs", "#[test] fn f() { }")
+ .file("benches/d.rs", r#"
+ #![feature(test)]
+ extern crate test;
+ #[bench] fn run1(_ben: &mut test::Bencher) { }"#);
+ p.build();
+
+ let ref host = rustc_host();
+
+ // Use RUSTFLAGS to pass an argument that will generate an error
+ assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
+ .arg("--lib").arg("--target").arg(host),
+ execs().with_status(101));
+ assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
+ .arg("--bin=a").arg("--target").arg(host),
+ execs().with_status(101));
+ assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
+ .arg("--example=b").arg("--target").arg(host),
+ execs().with_status(101));
+ assert_that(p.cargo("test").env("RUSTFLAGS", "-Z bogus")
+ .arg("--target").arg(host),
+ execs().with_status(101));
+ assert_that(p.cargo("bench").env("RUSTFLAGS", "-Z bogus")
+ .arg("--target").arg(host),
+ execs().with_status(101));
+}
+
+#[test]
+fn env_rustflags_build_script_with_target() {
+ // RUSTFLAGS should not be passed to rustc for build scripts
+ // when --target is specified.
+ // In this test if --cfg foo is passed the build will fail.
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() { }
+ #[cfg(foo)]
+ fn main() { }
+ "#);
+ p.build();
+
+ let host = rustc_host();
+ assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo")
+ .arg("--target").arg(host),
+ execs().with_status(0));
+}
+
+#[test]
+fn env_rustflags_build_script_dep_with_target() {
+ // RUSTFLAGS should not be passed to rustc for build scripts
+ // when --target is specified.
+ // In this test if --cfg foo is passed the build will fail.
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ build = "build.rs"
+
+ [build-dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() { }
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", r#"
+ fn bar() { }
+ #[cfg(foo)]
+ fn bar() { }
+ "#);
+ foo.build();
+ bar.build();
+
+ let host = rustc_host();
+ assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo")
+ .arg("--target").arg(host),
+ execs().with_status(0));
+}
+
+#[test]
+fn env_rustflags_plugin_with_target() {
+ // RUSTFLAGS should not be passed to rustc for plugins
+ // when --target is specified.
+ // In this test if --cfg foo is passed the build will fail.
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+
+ [lib]
+ name = "foo"
+ plugin = true
+ "#)
+ .file("src/lib.rs", r#"
+ fn main() { }
+ #[cfg(foo)]
+ fn main() { }
+ "#);
+ p.build();
+
+ let host = rustc_host();
+ assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo")
+ .arg("--target").arg(host),
+ execs().with_status(0));
+}
+
+#[test]
+fn env_rustflags_plugin_dep_with_target() {
+ // RUSTFLAGS should not be passed to rustc for plugins
+ // when --target is specified.
+ // In this test if --cfg foo is passed the build will fail.
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+
+ [lib]
+ name = "foo"
+ plugin = true
+
+ [dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/lib.rs", r#"
+ fn foo() { }
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+
+ [lib]
+ name = "bar"
+ "#)
+ .file("src/lib.rs", r#"
+ fn bar() { }
+ #[cfg(foo)]
+ fn bar() { }
+ "#);
+ foo.build();
+ bar.build();
+
+ let host = rustc_host();
+ assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo")
+ .arg("--target").arg(host),
+ execs().with_status(0));
+}
+
+#[test]
+fn env_rustflags_recompile() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+ // Setting RUSTFLAGS forces a recompile
+ assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus"),
+ execs().with_status(101));
+}
+
+#[test]
+fn env_rustflags_recompile2() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+ execs().with_status(0));
+ // Setting RUSTFLAGS forces a recompile
+ assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus"),
+ execs().with_status(101));
+}
+
+#[test]
+fn env_rustflags_no_recompile() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+ execs().with_status(0));
+ assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+ execs().with_stdout("").with_status(0));
+}
+
+#[test]
+fn build_rustflags_normal_source() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/bin/a.rs", "fn main() {}")
+ .file("examples/b.rs", "fn main() {}")
+ .file("tests/c.rs", "#[test] fn f() { }")
+ .file("benches/d.rs", r#"
+ #![feature(test)]
+ extern crate test;
+ #[bench] fn run1(_ben: &mut test::Bencher) { }"#)
+ .file(".cargo/config", r#"
+ [build]
+ rustflags = ["-Z", "bogus"]
+ "#);
+ p.build();
+
+ assert_that(p.cargo("build")
+ .arg("--lib"),
+ execs().with_status(101));
+ assert_that(p.cargo("build")
+ .arg("--bin=a"),
+ execs().with_status(101));
+ assert_that(p.cargo("build")
+ .arg("--example=b"),
+ execs().with_status(101));
+ assert_that(p.cargo("test"),
+ execs().with_status(101));
+ assert_that(p.cargo("bench"),
+ execs().with_status(101));
+}
+
+#[test]
+fn build_rustflags_build_script() {
+ // RUSTFLAGS should be passed to rustc for build scripts
+ // when --target is not specified.
+ // In this test if --cfg foo is passed the build will fail.
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() { }
+ #[cfg(not(foo))]
+ fn main() { }
+ "#)
+ .file(".cargo/config", r#"
+ [build]
+ rustflags = ["--cfg", "foo"]
+ "#);
+ p.build();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn build_rustflags_build_script_dep() {
+ // RUSTFLAGS should be passed to rustc for build scripts
+ // when --target is not specified.
+ // In this test if --cfg foo is not passed the build will fail.
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ build = "build.rs"
+
+ [build-dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() { }
+ "#)
+ .file(".cargo/config", r#"
+ [build]
+ rustflags = ["--cfg", "foo"]
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", r#"
+ fn bar() { }
+ #[cfg(not(foo))]
+ fn bar() { }
+ "#);
+ foo.build();
+ bar.build();
+
+ assert_that(foo.cargo("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn build_rustflags_plugin() {
+ // RUSTFLAGS should be passed to rustc for plugins
+ // when --target is not specified.
+ // In this test if --cfg foo is not passed the build will fail.
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+
+ [lib]
+ name = "foo"
+ plugin = true
+ "#)
+ .file("src/lib.rs", r#"
+ fn main() { }
+ #[cfg(not(foo))]
+ fn main() { }
+ "#)
+ .file(".cargo/config", r#"
+ [build]
+ rustflags = ["--cfg", "foo"]
+ "#);
+ p.build();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn build_rustflags_plugin_dep() {
+ // RUSTFLAGS should be passed to rustc for plugins
+ // when --target is not specified.
+ // In this test if --cfg foo is not passed the build will fail.
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+
+ [lib]
+ name = "foo"
+ plugin = true
+
+ [dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/lib.rs", r#"
+ fn foo() { }
+ "#)
+ .file(".cargo/config", r#"
+ [build]
+ rustflags = ["--cfg", "foo"]
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+
+ [lib]
+ name = "bar"
+ "#)
+ .file("src/lib.rs", r#"
+ fn bar() { }
+ #[cfg(not(foo))]
+ fn bar() { }
+ "#);
+ foo.build();
+ bar.build();
+
+ assert_that(foo.cargo("build"),
+ execs().with_status(0));
+}
+
+#[test]
+fn build_rustflags_normal_source_with_target() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/bin/a.rs", "fn main() {}")
+ .file("examples/b.rs", "fn main() {}")
+ .file("tests/c.rs", "#[test] fn f() { }")
+ .file("benches/d.rs", r#"
+ #![feature(test)]
+ extern crate test;
+ #[bench] fn run1(_ben: &mut test::Bencher) { }"#)
+ .file(".cargo/config", r#"
+ [build]
+ rustflags = ["-Z", "bogus"]
+ "#);
+ p.build();
+
+ let ref host = rustc_host();
+
+ // Use RUSTFLAGS to pass an argument that will generate an error
+ assert_that(p.cargo("build")
+ .arg("--lib").arg("--target").arg(host),
+ execs().with_status(101));
+ assert_that(p.cargo("build")
+ .arg("--bin=a").arg("--target").arg(host),
+ execs().with_status(101));
+ assert_that(p.cargo("build")
+ .arg("--example=b").arg("--target").arg(host),
+ execs().with_status(101));
+ assert_that(p.cargo("test")
+ .arg("--target").arg(host),
+ execs().with_status(101));
+ assert_that(p.cargo("bench")
+ .arg("--target").arg(host),
+ execs().with_status(101));
+}
+
+#[test]
+fn build_rustflags_build_script_with_target() {
+ // RUSTFLAGS should not be passed to rustc for build scripts
+ // when --target is specified.
+ // In this test if --cfg foo is passed the build will fail.
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ build = "build.rs"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() { }
+ #[cfg(foo)]
+ fn main() { }
+ "#)
+ .file(".cargo/config", r#"
+ [build]
+ rustflags = ["--cfg", "foo"]
+ "#);
+ p.build();
+
+ let host = rustc_host();
+ assert_that(p.cargo("build")
+ .arg("--target").arg(host),
+ execs().with_status(0));
+}
+
+#[test]
+fn build_rustflags_build_script_dep_with_target() {
+ // RUSTFLAGS should not be passed to rustc for build scripts
+ // when --target is specified.
+ // In this test if --cfg foo is passed the build will fail.
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ build = "build.rs"
+
+ [build-dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/lib.rs", "")
+ .file("build.rs", r#"
+ fn main() { }
+ "#)
+ .file(".cargo/config", r#"
+ [build]
+ rustflags = ["--cfg", "foo"]
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", r#"
+ fn bar() { }
+ #[cfg(foo)]
+ fn bar() { }
+ "#);
+ foo.build();
+ bar.build();
+
+ let host = rustc_host();
+ assert_that(foo.cargo("build")
+ .arg("--target").arg(host),
+ execs().with_status(0));
+}
+
+#[test]
+fn build_rustflags_plugin_with_target() {
+ // RUSTFLAGS should not be passed to rustc for plugins
+ // when --target is specified.
+ // In this test if --cfg foo is passed the build will fail.
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+
+ [lib]
+ name = "foo"
+ plugin = true
+ "#)
+ .file("src/lib.rs", r#"
+ fn main() { }
+ #[cfg(foo)]
+ fn main() { }
+ "#)
+ .file(".cargo/config", r#"
+ [build]
+ rustflags = ["--cfg", "foo"]
+ "#);
+ p.build();
+
+ let host = rustc_host();
+ assert_that(p.cargo("build")
+ .arg("--target").arg(host),
+ execs().with_status(0));
+}
+
+#[test]
+fn build_rustflags_plugin_dep_with_target() {
+ // RUSTFLAGS should not be passed to rustc for plugins
+ // when --target is specified.
+ // In this test if --cfg foo is passed the build will fail.
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+
+ [lib]
+ name = "foo"
+ plugin = true
+
+ [dependencies.bar]
+ path = "../bar"
+ "#)
+ .file("src/lib.rs", r#"
+ fn foo() { }
+ "#)
+ .file(".cargo/config", r#"
+ [build]
+ rustflags = ["--cfg", "foo"]
+ "#);
+ let bar = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+
+ [lib]
+ name = "bar"
+ "#)
+ .file("src/lib.rs", r#"
+ fn bar() { }
+ #[cfg(foo)]
+ fn bar() { }
+ "#);
+ foo.build();
+ bar.build();
+
+ let host = rustc_host();
+ assert_that(foo.cargo("build")
+ .arg("--target").arg(host),
+ execs().with_status(0));
+}
+
+#[test]
+fn build_rustflags_recompile() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0));
+
+ // Setting RUSTFLAGS forces a recompile
+ let config = r#"
+ [build]
+ rustflags = ["-Z", "bogus"]
+ "#;
+ let config_file = paths::root().join("foo/.cargo/config");
+ fs::create_dir_all(config_file.parent().unwrap()).unwrap();
+ let mut config_file = File::create(config_file).unwrap();
+ config_file.write_all(config.as_bytes()).unwrap();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(101));
+}
+
+#[test]
+fn build_rustflags_recompile2() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+ execs().with_status(0));
+
+ // Setting RUSTFLAGS forces a recompile
+ let config = r#"
+ [build]
+ rustflags = ["-Z", "bogus"]
+ "#;
+ let config_file = paths::root().join("foo/.cargo/config");
+ fs::create_dir_all(config_file.parent().unwrap()).unwrap();
+ let mut config_file = File::create(config_file).unwrap();
+ config_file.write_all(config.as_bytes()).unwrap();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(101));
+}
+
+#[test]
+fn build_rustflags_no_recompile() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", r#"
+ [build]
+ rustflags = ["--cfg", "foo"]
+ "#);
+ p.build();
+
+ assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+ execs().with_status(0));
+ assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+ execs().with_stdout("").with_status(0));
+}
--- /dev/null
+extern crate cargo;
+extern crate cargotest;
+extern crate hamcrest;
+extern crate url;
+
+use std::fs::{self, File};
+use std::io::prelude::*;
+use std::path::PathBuf;
+
+use cargo::util::ProcessBuilder;
+use cargotest::support::execs;
+use cargotest::support::git::repo;
+use cargotest::support::paths;
+use hamcrest::assert_that;
+use url::Url;
+
+fn registry_path() -> PathBuf { paths::root().join("registry") }
+fn registry() -> Url { Url::from_file_path(&*registry_path()).ok().unwrap() }
+fn api_path() -> PathBuf { paths::root().join("api") }
+fn api() -> Url { Url::from_file_path(&*api_path()).ok().unwrap() }
+
+fn setup() {
+ let config = paths::root().join(".cargo/config");
+ fs::create_dir_all(config.parent().unwrap()).unwrap();
+ File::create(&config).unwrap().write_all(format!(r#"
+ [registry]
+ index = "{reg}"
+ "#, reg = registry()).as_bytes()).unwrap();
+ fs::create_dir_all(&api_path().join("api/v1")).unwrap();
+
+ repo(®istry_path())
+ .file("config.json", &format!(r#"{{
+ "dl": "{0}",
+ "api": "{0}"
+ }}"#, api()))
+ .build();
+}
+
+fn cargo_process(s: &str) -> ProcessBuilder {
+ let mut b = cargotest::cargo_process();
+ b.arg(s);
+ return b
+}
+
+#[test]
+fn simple() {
+ setup();
+
+ let contents = r#"{
+ "crates": [{
+ "created_at": "2014-11-16T20:17:35Z",
+ "description": "Design by contract style assertions for Rust",
+ "documentation": null,
+ "downloads": 2,
+ "homepage": null,
+ "id": "hoare",
+ "keywords": [],
+ "license": null,
+ "links": {
+ "owners": "/api/v1/crates/hoare/owners",
+ "reverse_dependencies": "/api/v1/crates/hoare/reverse_dependencies",
+ "version_downloads": "/api/v1/crates/hoare/downloads",
+ "versions": "/api/v1/crates/hoare/versions"
+ },
+ "max_version": "0.1.1",
+ "name": "hoare",
+ "repository": "https://github.com/nick29581/libhoare",
+ "updated_at": "2014-11-20T21:49:21Z",
+ "versions": null
+ }],
+ "meta": {
+ "total": 1
+ }
+ }"#;
+ let base = api_path().join("api/v1/crates");
+
+ // Older versions of curl don't peel off query parameters when looking for
+ // filenames, so just make both files.
+ //
+ // On windows, though, `?` is an invalid character, but we always build curl
+ // from source there anyway!
+ File::create(&base).unwrap().write_all(contents.as_bytes()).unwrap();
+ if !cfg!(windows) {
+ File::create(&base.with_file_name("crates?q=postgres&per_page=10")).unwrap()
+ .write_all(contents.as_bytes()).unwrap();
+ }
+
+ assert_that(cargo_process("search").arg("postgres"),
+ execs().with_status(0)
+ .with_stderr("\
+[UPDATING] registry `[..]`")
+ .with_stdout("\
+hoare (0.1.1) Design by contract style assertions for Rust"));
+}
+
+#[test]
+fn multiple_query_params() {
+ setup();
+
+ let contents = r#"{
+ "crates": [{
+ "created_at": "2014-11-16T20:17:35Z",
+ "description": "Design by contract style assertions for Rust",
+ "documentation": null,
+ "downloads": 2,
+ "homepage": null,
+ "id": "hoare",
+ "keywords": [],
+ "license": null,
+ "links": {
+ "owners": "/api/v1/crates/hoare/owners",
+ "reverse_dependencies": "/api/v1/crates/hoare/reverse_dependencies",
+ "version_downloads": "/api/v1/crates/hoare/downloads",
+ "versions": "/api/v1/crates/hoare/versions"
+ },
+ "max_version": "0.1.1",
+ "name": "hoare",
+ "repository": "https://github.com/nick29581/libhoare",
+ "updated_at": "2014-11-20T21:49:21Z",
+ "versions": null
+ }],
+ "meta": {
+ "total": 1
+ }
+ }"#;
+ let base = api_path().join("api/v1/crates");
+
+ // Older versions of curl don't peel off query parameters when looking for
+ // filenames, so just make both files.
+ //
+ // On windows, though, `?` is an invalid character, but we always build curl
+ // from source there anyway!
+ File::create(&base).unwrap().write_all(contents.as_bytes()).unwrap();
+ if !cfg!(windows) {
+ File::create(&base.with_file_name("crates?q=postgres+sql&per_page=10")).unwrap()
+ .write_all(contents.as_bytes()).unwrap();
+ }
+
+ assert_that(cargo_process("search").arg("postgres").arg("sql"),
+ execs().with_status(0)
+ .with_stderr("\
+[UPDATING] registry `[..]`")
+ .with_stdout("\
+hoare (0.1.1) Design by contract style assertions for Rust"));
+}
+
+#[test]
+fn help() {
+ assert_that(cargo_process("search").arg("-h"),
+ execs().with_status(0));
+ assert_that(cargo_process("help").arg("search"),
+ execs().with_status(0));
+}
--- /dev/null
+extern crate cargo;
+extern crate cargotest;
+extern crate hamcrest;
+extern crate term;
+
+use std::io::prelude::*;
+use std::io;
+use std::sync::{Arc, Mutex};
+
+use cargo::core::shell::ColorConfig::{Auto,Always, Never};
+use cargo::core::shell::{Shell, ShellConfig};
+use cargo::util::CargoResult;
+use cargotest::support::{Tap, execs, shell_writes};
+use hamcrest::{assert_that};
+use term::{Terminal, TerminfoTerminal, color};
+
+struct Sink(Arc<Mutex<Vec<u8>>>);
+
+impl Write for Sink {
+ fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+ Write::write(&mut *self.0.lock().unwrap(), data)
+ }
+ fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
+
+#[test]
+fn non_tty() {
+ let config = ShellConfig { color_config: Auto, tty: false };
+ let a = Arc::new(Mutex::new(Vec::new()));
+
+ Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| {
+ shell.say("Hey Alex", color::RED).unwrap();
+ });
+ let buf = a.lock().unwrap().clone();
+ assert_that(&buf[..], shell_writes("Hey Alex\n"));
+}
+
+#[test]
+fn color_explicitly_disabled() {
+ let term = TerminfoTerminal::new(Vec::new());
+ if term.is_none() { return }
+
+ let config = ShellConfig { color_config: Never, tty: true };
+ let a = Arc::new(Mutex::new(Vec::new()));
+
+ Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| {
+ shell.say("Hey Alex", color::RED).unwrap();
+ });
+ let buf = a.lock().unwrap().clone();
+ assert_that(&buf[..], shell_writes("Hey Alex\n"));
+}
+
+#[test]
+fn colored_shell() {
+ let term = TerminfoTerminal::new(Vec::new());
+ if term.is_none() { return }
+
+ let config = ShellConfig { color_config: Auto, tty: true };
+ let a = Arc::new(Mutex::new(Vec::new()));
+
+ Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| {
+ shell.say("Hey Alex", color::RED).unwrap();
+ });
+ let buf = a.lock().unwrap().clone();
+ assert_that(&buf[..],
+ shell_writes(colored_output("Hey Alex\n",
+ color::RED).unwrap()));
+}
+
+#[test]
+fn color_explicitly_enabled() {
+ let term = TerminfoTerminal::new(Vec::new());
+ if term.is_none() { return }
+
+ let config = ShellConfig { color_config: Always, tty: false };
+ let a = Arc::new(Mutex::new(Vec::new()));
+
+ Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| {
+ shell.say("Hey Alex", color::RED).unwrap();
+ });
+ let buf = a.lock().unwrap().clone();
+ assert_that(&buf[..],
+ shell_writes(colored_output("Hey Alex\n",
+ color::RED).unwrap()));
+}
+
+#[test]
+fn no_term() {
+ // Verify that shell creation is successful when $TERM does not exist.
+ assert_that(cargotest::cargo_process().env_remove("TERM"),
+ execs().with_stderr(""));
+}
+
+fn colored_output(string: &str, color: color::Color) -> CargoResult<String> {
+ let mut term = TerminfoTerminal::new(Vec::new()).unwrap();
+ try!(term.reset());
+ try!(term.fg(color));
+ try!(write!(&mut term, "{}", string));
+ try!(term.reset());
+ try!(term.flush());
+ Ok(String::from_utf8_lossy(term.get_ref()).to_string())
+}
+++ /dev/null
-use std::fs::{self, File};
-use std::io::prelude::*;
-use std::path::{Path, PathBuf};
-
-use url::Url;
-use git2;
-
-use cargo::util::ProcessError;
-use support::{ProjectBuilder, project, path2url};
-
-pub struct RepoBuilder {
- repo: git2::Repository,
- files: Vec<PathBuf>,
-}
-
-pub fn repo(p: &Path) -> RepoBuilder { RepoBuilder::init(p) }
-
-impl RepoBuilder {
- pub fn init(p: &Path) -> RepoBuilder {
- fs::create_dir_all(p.parent().unwrap()).unwrap();
- let repo = git2::Repository::init(p).unwrap();
- {
- let mut config = repo.config().unwrap();
- config.set_str("user.name", "name").unwrap();
- config.set_str("user.email", "email").unwrap();
- }
- RepoBuilder { repo: repo, files: Vec::new() }
- }
-
- pub fn file(self, path: &str, contents: &str) -> RepoBuilder {
- let mut me = self.nocommit_file(path, contents);
- me.files.push(PathBuf::from(path));
- me
- }
-
- pub fn nocommit_file(self, path: &str, contents: &str) -> RepoBuilder {
- let dst = self.repo.workdir().unwrap().join(path);
- fs::create_dir_all(dst.parent().unwrap()).unwrap();
- File::create(&dst).unwrap().write_all(contents.as_bytes()).unwrap();
- self
- }
-
- pub fn build(&self) {
- let mut index = self.repo.index().unwrap();
- for file in self.files.iter() {
- index.add_path(file).unwrap();
- }
- index.write().unwrap();
- let id = index.write_tree().unwrap();
- let tree = self.repo.find_tree(id).unwrap();
- let sig = self.repo.signature().unwrap();
- self.repo.commit(Some("HEAD"), &sig, &sig,
- "Initial commit", &tree, &[]).unwrap();
- }
-
- pub fn root(&self) -> &Path {
- self.repo.workdir().unwrap()
- }
-
- pub fn url(&self) -> Url {
- path2url(self.repo.workdir().unwrap().to_path_buf())
- }
-}
-
-pub fn new<F>(name: &str, callback: F) -> Result<ProjectBuilder, ProcessError>
- where F: FnOnce(ProjectBuilder) -> ProjectBuilder
-{
- let mut git_project = project(name);
- git_project = callback(git_project);
- git_project.build();
-
- let repo = git2::Repository::init(&git_project.root()).unwrap();
- let mut cfg = repo.config().unwrap();
- cfg.set_str("user.email", "foo@bar.com").unwrap();
- cfg.set_str("user.name", "Foo Bar").unwrap();
- drop(cfg);
- add(&repo);
- commit(&repo);
- Ok(git_project)
-}
-
-pub fn add(repo: &git2::Repository) {
- // FIXME(libgit2/libgit2#2514): apparently add_all will add all submodules
- // as well, and then fail b/c they're a directory. As a stopgap, we just
- // ignore all submodules.
- let mut s = repo.submodules().unwrap();
- for submodule in s.iter_mut() {
- submodule.add_to_index(false).unwrap();
- }
- let mut index = repo.index().unwrap();
- index.add_all(["*"].iter(), git2::ADD_DEFAULT,
- Some(&mut (|a, _b| {
- if s.iter().any(|s| a.starts_with(s.path())) {1} else {0}
- }))).unwrap();
- index.write().unwrap();
-}
-
-pub fn add_submodule<'a>(repo: &'a git2::Repository, url: &str,
- path: &Path) -> git2::Submodule<'a>
-{
- let path = path.to_str().unwrap().replace(r"\", "/");
- let mut s = repo.submodule(url, Path::new(&path), false).unwrap();
- let subrepo = s.open().unwrap();
- subrepo.remote_add_fetch("origin", "refs/heads/*:refs/heads/*").unwrap();
- let mut origin = subrepo.find_remote("origin").unwrap();
- origin.fetch(&[], None, None).unwrap();
- subrepo.checkout_head(None).unwrap();
- s.add_finalize().unwrap();
- return s;
-}
-
-pub fn commit(repo: &git2::Repository) -> git2::Oid {
- let tree_id = repo.index().unwrap().write_tree().unwrap();
- let sig = repo.signature().unwrap();
- let mut parents = Vec::new();
- match repo.head().ok().map(|h| h.target().unwrap()) {
- Some(parent) => parents.push(repo.find_commit(parent).unwrap()),
- None => {}
- }
- let parents = parents.iter().collect::<Vec<_>>();
- repo.commit(Some("HEAD"), &sig, &sig, "test",
- &repo.find_tree(tree_id).unwrap(),
- &parents).unwrap()
-}
-
-pub fn tag(repo: &git2::Repository, name: &str) {
- let head = repo.head().unwrap().target().unwrap();
- repo.tag(name,
- &repo.find_object(head, None).unwrap(),
- &repo.signature().unwrap(),
- "make a new tag",
- false).unwrap();
-}
+++ /dev/null
-use std::env;
-use std::error::Error;
-use std::ffi::OsStr;
-use std::fmt;
-use std::fs;
-use std::io::prelude::*;
-use std::os;
-use std::path::{Path, PathBuf};
-use std::process::Output;
-use std::str;
-use std::usize;
-
-use rustc_serialize::json::Json;
-use url::Url;
-use hamcrest as ham;
-use cargo::util::ProcessBuilder;
-use cargo::util::ProcessError;
-use cargo::util::process;
-
-use support::paths::CargoPathExt;
-
-pub mod paths;
-pub mod git;
-pub mod registry;
-
-/*
- *
- * ===== Builders =====
- *
- */
-
-#[derive(PartialEq,Clone)]
-struct FileBuilder {
- path: PathBuf,
- body: String
-}
-
-impl FileBuilder {
- pub fn new(path: PathBuf, body: &str) -> FileBuilder {
- FileBuilder { path: path, body: body.to_string() }
- }
-
- fn mk(&self) -> Result<(), String> {
- try!(mkdir_recursive(&self.dirname()));
-
- let mut file = try!(
- fs::File::create(&self.path)
- .with_err_msg(format!("Could not create file; path={}",
- self.path.display())));
-
- file.write_all(self.body.as_bytes())
- .with_err_msg(format!("Could not write to file; path={}",
- self.path.display()))
- }
-
- fn dirname(&self) -> &Path {
- self.path.parent().unwrap()
- }
-}
-
-#[derive(PartialEq,Clone)]
-struct SymlinkBuilder {
- dst: PathBuf,
- src: PathBuf,
-}
-
-impl SymlinkBuilder {
- pub fn new(dst: PathBuf, src: PathBuf) -> SymlinkBuilder {
- SymlinkBuilder { dst: dst, src: src }
- }
-
- #[cfg(unix)]
- fn mk(&self) -> Result<(), String> {
- try!(mkdir_recursive(&self.dirname()));
-
- os::unix::fs::symlink(&self.dst, &self.src)
- .with_err_msg(format!("Could not create symlink; dst={} src={}",
- self.dst.display(), self.src.display()))
- }
-
- #[cfg(windows)]
- fn mk(&self) -> Result<(), String> {
- try!(mkdir_recursive(&self.dirname()));
-
- os::windows::fs::symlink_file(&self.dst, &self.src)
- .with_err_msg(format!("Could not create symlink; dst={} src={}",
- self.dst.display(), self.src.display()))
- }
-
- fn dirname(&self) -> &Path {
- self.src.parent().unwrap()
- }
-}
-
-#[derive(PartialEq,Clone)]
-pub struct ProjectBuilder {
- name: String,
- root: PathBuf,
- files: Vec<FileBuilder>,
- symlinks: Vec<SymlinkBuilder>
-}
-
-impl ProjectBuilder {
- pub fn new(name: &str, root: PathBuf) -> ProjectBuilder {
- ProjectBuilder {
- name: name.to_string(),
- root: root,
- files: vec![],
- symlinks: vec![]
- }
- }
-
- pub fn root(&self) -> PathBuf {
- self.root.clone()
- }
-
- pub fn url(&self) -> Url { path2url(self.root()) }
-
- pub fn bin(&self, b: &str) -> PathBuf {
- self.build_dir().join("debug").join(&format!("{}{}", b,
- env::consts::EXE_SUFFIX))
- }
-
- pub fn release_bin(&self, b: &str) -> PathBuf {
- self.build_dir().join("release").join(&format!("{}{}", b,
- env::consts::EXE_SUFFIX))
- }
-
- pub fn target_bin(&self, target: &str, b: &str) -> PathBuf {
- self.build_dir().join(target).join("debug")
- .join(&format!("{}{}", b, env::consts::EXE_SUFFIX))
- }
-
- pub fn build_dir(&self) -> PathBuf {
- self.root.join("target")
- }
-
- pub fn process<T: AsRef<OsStr>>(&self, program: T) -> ProcessBuilder {
- let mut p = ::process(program);
- p.cwd(self.root());
- return p
- }
-
- pub fn cargo(&self, cmd: &str) -> ProcessBuilder {
- let mut p = self.process(&cargo_dir().join("cargo"));
- p.arg(cmd);
- return p;
- }
-
- pub fn cargo_process(&self, cmd: &str) -> ProcessBuilder {
- self.build();
- self.cargo(cmd)
- }
-
- pub fn file<B: AsRef<Path>>(mut self, path: B,
- body: &str) -> ProjectBuilder {
- self.files.push(FileBuilder::new(self.root.join(path), body));
- self
- }
-
- pub fn symlink<T: AsRef<Path>>(mut self, dst: T,
- src: T) -> ProjectBuilder {
- self.symlinks.push(SymlinkBuilder::new(self.root.join(dst),
- self.root.join(src)));
- self
- }
-
- // TODO: return something different than a ProjectBuilder
- pub fn build(&self) -> &ProjectBuilder {
- match self.build_with_result() {
- Err(e) => panic!(e),
- _ => return self
- }
- }
-
- pub fn build_with_result(&self) -> Result<(), String> {
- // First, clean the directory if it already exists
- try!(self.rm_root());
-
- // Create the empty directory
- try!(mkdir_recursive(&self.root));
-
- for file in self.files.iter() {
- try!(file.mk());
- }
-
- for symlink in self.symlinks.iter() {
- try!(symlink.mk());
- }
-
- Ok(())
- }
-
- fn rm_root(&self) -> Result<(), String> {
- if self.root.c_exists() {
- rmdir_recursive(&self.root)
- } else {
- Ok(())
- }
- }
-}
-
-// Generates a project layout
-pub fn project(name: &str) -> ProjectBuilder {
- ProjectBuilder::new(name, paths::root().join(name))
-}
-
-// === Helpers ===
-
-pub fn mkdir_recursive(path: &Path) -> Result<(), String> {
- fs::create_dir_all(path)
- .with_err_msg(format!("could not create directory; path={}",
- path.display()))
-}
-
-pub fn rmdir_recursive(path: &Path) -> Result<(), String> {
- path.rm_rf()
- .with_err_msg(format!("could not rm directory; path={}",
- path.display()))
-}
-
-pub fn main_file(println: &str, deps: &[&str]) -> String {
- let mut buf = String::new();
-
- for dep in deps.iter() {
- buf.push_str(&format!("extern crate {};\n", dep));
- }
-
- buf.push_str("fn main() { println!(");
- buf.push_str(&println);
- buf.push_str("); }\n");
-
- buf.to_string()
-}
-
-trait ErrMsg<T> {
- fn with_err_msg(self, val: String) -> Result<T, String>;
-}
-
-impl<T, E: fmt::Display> ErrMsg<T> for Result<T, E> {
- fn with_err_msg(self, val: String) -> Result<T, String> {
- match self {
- Ok(val) => Ok(val),
- Err(err) => Err(format!("{}; original={}", val, err))
- }
- }
-}
-
-// Path to cargo executables
-pub fn cargo_dir() -> PathBuf {
- env::var_os("CARGO_BIN_PATH").map(PathBuf::from).or_else(|| {
- env::current_exe().ok().as_ref().and_then(|s| s.parent())
- .map(|s| s.to_path_buf())
- }).unwrap_or_else(|| {
- panic!("CARGO_BIN_PATH wasn't set. Cannot continue running test")
- })
-}
-
-/// Returns an absolute path in the filesystem that `path` points to. The
-/// returned path does not contain any symlinks in its hierarchy.
-/*
- *
- * ===== Matchers =====
- *
- */
-
-#[derive(Clone)]
-pub struct Execs {
- expect_stdout: Option<String>,
- expect_stdin: Option<String>,
- expect_stderr: Option<String>,
- expect_exit_code: Option<i32>,
- expect_stdout_contains: Vec<String>,
- expect_stderr_contains: Vec<String>,
- expect_json: Option<Json>,
-}
-
-impl Execs {
- pub fn with_stdout<S: ToString>(mut self, expected: S) -> Execs {
- self.expect_stdout = Some(expected.to_string());
- self
- }
-
- pub fn with_stderr<S: ToString>(mut self, expected: S) -> Execs {
- self.expect_stderr = Some(expected.to_string());
- self
- }
-
- pub fn with_status(mut self, expected: i32) -> Execs {
- self.expect_exit_code = Some(expected);
- self
- }
-
- pub fn with_stdout_contains<S: ToString>(mut self, expected: S) -> Execs {
- self.expect_stdout_contains.push(expected.to_string());
- self
- }
-
- pub fn with_stderr_contains<S: ToString>(mut self, expected: S) -> Execs {
- self.expect_stderr_contains.push(expected.to_string());
- self
- }
-
- pub fn with_json(mut self, expected: &str) -> Execs {
- self.expect_json = Some(Json::from_str(expected).unwrap());
- self
- }
-
- fn match_output(&self, actual: &Output) -> ham::MatchResult {
- self.match_status(actual)
- .and(self.match_stdout(actual))
- .and(self.match_stderr(actual))
- }
-
- fn match_status(&self, actual: &Output) -> ham::MatchResult {
- match self.expect_exit_code {
- None => ham::success(),
- Some(code) => {
- ham::expect(
- actual.status.code() == Some(code),
- format!("exited with {}\n--- stdout\n{}\n--- stderr\n{}",
- actual.status,
- String::from_utf8_lossy(&actual.stdout),
- String::from_utf8_lossy(&actual.stderr)))
- }
- }
- }
-
- fn match_stdout(&self, actual: &Output) -> ham::MatchResult {
- try!(self.match_std(self.expect_stdout.as_ref(), &actual.stdout,
- "stdout", &actual.stderr, false));
- for expect in self.expect_stdout_contains.iter() {
- try!(self.match_std(Some(expect), &actual.stdout, "stdout",
- &actual.stderr, true));
- }
- for expect in self.expect_stderr_contains.iter() {
- try!(self.match_std(Some(expect), &actual.stderr, "stderr",
- &actual.stdout, true));
- }
-
- if let Some(ref expect_json) = self.expect_json {
- try!(self.match_json(expect_json, &actual.stdout));
- }
- Ok(())
- }
-
- fn match_stderr(&self, actual: &Output) -> ham::MatchResult {
- self.match_std(self.expect_stderr.as_ref(), &actual.stderr,
- "stderr", &actual.stdout, false)
- }
-
- fn match_std(&self, expected: Option<&String>, actual: &[u8],
- description: &str, extra: &[u8],
- partial: bool) -> ham::MatchResult {
- let out = match expected {
- Some(out) => substitute_macros(out),
- None => return ham::success(),
- };
- let actual = match str::from_utf8(actual) {
- Err(..) => return Err(format!("{} was not utf8 encoded",
- description)),
- Ok(actual) => actual,
- };
- // Let's not deal with \r\n vs \n on windows...
- let actual = actual.replace("\r", "");
- let actual = actual.replace("\t", "<tab>");
-
- let mut a = actual.lines();
- let e = out.lines();
-
- let diffs = if partial {
- let mut min = self.diff_lines(a.clone(), e.clone(), partial);
- while let Some(..) = a.next() {
- let a = self.diff_lines(a.clone(), e.clone(), partial);
- if a.len() < min.len() {
- min = a;
- }
- }
- min
- } else {
- self.diff_lines(a, e, partial)
- };
- ham::expect(diffs.is_empty(),
- format!("differences:\n\
- {}\n\n\
- other output:\n\
- `{}`", diffs.join("\n"),
- String::from_utf8_lossy(extra)))
-
- }
-
- fn match_json(&self, expected: &Json, stdout: &[u8]) -> ham::MatchResult {
- let stdout = match str::from_utf8(stdout) {
- Err(..) => return Err("stdout was not utf8 encoded".to_owned()),
- Ok(stdout) => stdout,
- };
-
- let actual = match Json::from_str(stdout) {
- Err(..) => return Err(format!("Invalid json {}", stdout)),
- Ok(actual) => actual,
- };
-
- match find_mismatch(expected, &actual) {
- Some((expected_part, actual_part)) => Err(format!(
- "JSON mismatch\nExpected:\n{}\nWas:\n{}\nExpected part:\n{}\nActual part:\n{}\n",
- expected.pretty(), actual.pretty(),
- expected_part.pretty(), actual_part.pretty()
- )),
- None => Ok(()),
- }
- }
-
- fn diff_lines<'a>(&self, actual: str::Lines<'a>, expected: str::Lines<'a>,
- partial: bool) -> Vec<String> {
- let actual = actual.take(if partial {
- expected.clone().count()
- } else {
- usize::MAX
- });
- zip_all(actual, expected).enumerate().filter_map(|(i, (a,e))| {
- match (a, e) {
- (Some(a), Some(e)) => {
- if lines_match(&e, &a) {
- None
- } else {
- Some(format!("{:3} - |{}|\n + |{}|\n", i, e, a))
- }
- },
- (Some(a), None) => {
- Some(format!("{:3} -\n + |{}|\n", i, a))
- },
- (None, Some(e)) => {
- Some(format!("{:3} - |{}|\n +\n", i, e))
- },
- (None, None) => panic!("Cannot get here")
- }
- }).collect()
- }
-}
-
-fn lines_match(expected: &str, mut actual: &str) -> bool {
- for (i, part) in expected.split("[..]").enumerate() {
- match actual.find(part) {
- Some(j) => {
- if i == 0 && j != 0 {
- return false
- }
- actual = &actual[j + part.len()..];
- }
- None => {
- return false
- }
- }
- }
- actual.is_empty() || expected.ends_with("[..]")
-}
-
-#[test]
-fn lines_match_works() {
- assert!(lines_match("a b", "a b"));
- assert!(lines_match("a[..]b", "a b"));
- assert!(lines_match("a[..]", "a b"));
- assert!(lines_match("[..]", "a b"));
- assert!(lines_match("[..]b", "a b"));
-
- assert!(!lines_match("[..]b", "c"));
- assert!(!lines_match("b", "c"));
- assert!(!lines_match("b", "cb"));
-}
-
-// Compares JSON object for approximate equality.
-// You can use `[..]` wildcard in strings (useful for OS dependent things such as paths).
-// Arrays are sorted before comparison.
-fn find_mismatch<'a>(expected: &'a Json, actual: &'a Json) -> Option<(&'a Json, &'a Json)> {
- use rustc_serialize::json::Json::*;
- match (expected, actual) {
- (&I64(l), &I64(r)) if l == r => None,
- (&F64(l), &F64(r)) if l == r => None,
- (&U64(l), &U64(r)) if l == r => None,
- (&Boolean(l), &Boolean(r)) if l == r => None,
- (&String(ref l), &String(ref r)) if lines_match(l, r) => None,
- (&Array(ref l), &Array(ref r)) => {
- if l.len() != r.len() {
- return Some((expected, actual));
- }
-
- fn sorted(xs: &Vec<Json>) -> Vec<&Json> {
- let mut result = xs.iter().collect::<Vec<_>>();
- // `unwrap` should be safe because JSON spec does not allow NaNs
- result.sort_by(|x, y| x.partial_cmp(y).unwrap());
- result
- }
-
- sorted(l).iter().zip(sorted(r))
- .filter_map(|(l, r)| find_mismatch(l, r))
- .nth(0)
- }
- (&Object(ref l), &Object(ref r)) => {
- let same_keys = l.len() == r.len() && l.keys().all(|k| r.contains_key(k));
- if !same_keys {
- return Some((expected, actual));
- }
-
- l.values().zip(r.values())
- .filter_map(|(l, r)| find_mismatch(l, r))
- .nth(0)
- }
- (&Null, &Null) => None,
- _ => Some((expected, actual)),
- }
-
-}
-
-struct ZipAll<I1: Iterator, I2: Iterator> {
- first: I1,
- second: I2,
-}
-
-impl<T, I1: Iterator<Item=T>, I2: Iterator<Item=T>> Iterator for ZipAll<I1, I2> {
- type Item = (Option<T>, Option<T>);
- fn next(&mut self) -> Option<(Option<T>, Option<T>)> {
- let first = self.first.next();
- let second = self.second.next();
-
- match (first, second) {
- (None, None) => None,
- (a, b) => Some((a, b))
- }
- }
-}
-
-fn zip_all<T, I1: Iterator<Item=T>, I2: Iterator<Item=T>>(a: I1, b: I2) -> ZipAll<I1, I2> {
- ZipAll {
- first: a,
- second: b,
- }
-}
-
-impl fmt::Display for Execs {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "execs")
- }
-}
-
-impl ham::Matcher<ProcessBuilder> for Execs {
- fn matches(&self, mut process: ProcessBuilder) -> ham::MatchResult {
- self.matches(&mut process)
- }
-}
-
-impl<'a> ham::Matcher<&'a mut ProcessBuilder> for Execs {
- fn matches(&self, process: &'a mut ProcessBuilder) -> ham::MatchResult {
- let res = process.exec_with_output();
-
- match res {
- Ok(out) => self.match_output(&out),
- Err(ProcessError { output: Some(ref out), .. }) => {
- self.match_output(out)
- }
- Err(e) => {
- let mut s = format!("could not exec process {}: {}", process, e);
- match e.cause() {
- Some(cause) => s.push_str(&format!("\ncaused by: {}",
- cause.description())),
- None => {}
- }
- Err(s)
- }
- }
- }
-}
-
-impl ham::Matcher<Output> for Execs {
- fn matches(&self, output: Output) -> ham::MatchResult {
- self.match_output(&output)
- }
-}
-
-pub fn execs() -> Execs {
- Execs {
- expect_stdout: None,
- expect_stderr: None,
- expect_stdin: None,
- expect_exit_code: None,
- expect_stdout_contains: Vec::new(),
- expect_stderr_contains: Vec::new(),
- expect_json: None,
- }
-}
-
-#[derive(Clone)]
-pub struct ShellWrites {
- expected: String
-}
-
-impl fmt::Display for ShellWrites {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "`{}` written to the shell", self.expected)
- }
-}
-
-impl<'a> ham::Matcher<&'a [u8]> for ShellWrites {
- fn matches(&self, actual: &[u8])
- -> ham::MatchResult
- {
- let actual = String::from_utf8_lossy(actual);
- let actual = actual.to_string();
- ham::expect(actual == self.expected, actual)
- }
-}
-
-pub fn shell_writes<T: fmt::Display>(string: T) -> ShellWrites {
- ShellWrites { expected: string.to_string() }
-}
-
-pub trait Tap {
- fn tap<F: FnOnce(&mut Self)>(mut self, callback: F) -> Self;
-}
-
-impl<T> Tap for T {
- fn tap<F: FnOnce(&mut Self)>(mut self, callback: F) -> T {
- callback(&mut self);
- self
- }
-}
-
-pub fn basic_bin_manifest(name: &str) -> String {
- format!(r#"
- [package]
-
- name = "{}"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [[bin]]
-
- name = "{}"
- "#, name, name)
-}
-
-pub fn basic_lib_manifest(name: &str) -> String {
- format!(r#"
- [package]
-
- name = "{}"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib]
-
- name = "{}"
- "#, name, name)
-}
-
-pub fn path2url(p: PathBuf) -> Url {
- Url::from_file_path(&*p).ok().unwrap()
-}
-
-fn substitute_macros(input: &str) -> String {
- let macros = [
- ("[RUNNING]", " Running"),
- ("[COMPILING]", " Compiling"),
- ("[ERROR]", "error:"),
- ("[WARNING]", "warning:"),
- ("[DOCUMENTING]", " Documenting"),
- ("[FRESH]", " Fresh"),
- ("[UPDATING]", " Updating"),
- ("[ADDING]", " Adding"),
- ("[REMOVING]", " Removing"),
- ("[DOCTEST]", " Doc-tests"),
- ("[PACKAGING]", " Packaging"),
- ("[DOWNLOADING]", " Downloading"),
- ("[UPLOADING]", " Uploading"),
- ("[VERIFYING]", " Verifying"),
- ("[ARCHIVING]", " Archiving"),
- ("[INSTALLING]", " Installing"),
- ("[REPLACING]", " Replacing")
- ];
- let mut result = input.to_owned();
- for &(pat, subst) in macros.iter() {
- result = result.replace(pat, subst)
- }
- return result;
-}
+++ /dev/null
-use std::env;
-use std::cell::Cell;
-use std::fs;
-use std::io::{self, ErrorKind};
-use std::path::{Path, PathBuf};
-use std::sync::{Once, ONCE_INIT};
-use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
-
-use filetime::{self, FileTime};
-
-static CARGO_INTEGRATION_TEST_DIR : &'static str = "cit";
-static NEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;
-
-thread_local!(static TASK_ID: usize = NEXT_ID.fetch_add(1, Ordering::SeqCst));
-
-fn init() {
- static GLOBAL_INIT: Once = ONCE_INIT;
- thread_local!(static LOCAL_INIT: Cell<bool> = Cell::new(false));
- GLOBAL_INIT.call_once(|| {
- global_root().mkdir_p().unwrap();
- });
- LOCAL_INIT.with(|i| {
- if i.get() {
- return
- }
- i.set(true);
- root().rm_rf().unwrap();
- home().mkdir_p().unwrap();
- })
-}
-
-fn global_root() -> PathBuf {
- let mut path = env::current_exe().unwrap();
- path.pop(); // chop off exe name
- path.pop(); // chop off 'debug'
-
- // If `cargo test` is run manually then our path looks like
- // `target/debug/foo`, in which case our `path` is already pointing at
- // `target`. If, however, `cargo test --target $target` is used then the
- // output is `target/$target/debug/foo`, so our path is pointing at
- // `target/$target`. Here we conditionally pop the `$target` name.
- if path.file_name().and_then(|s| s.to_str()) != Some("target") {
- path.pop();
- }
-
- path.join(CARGO_INTEGRATION_TEST_DIR)
-}
-
-pub fn root() -> PathBuf {
- init();
- global_root().join(&TASK_ID.with(|my_id| format!("t{}", my_id)))
-}
-
-pub fn home() -> PathBuf {
- root().join("home")
-}
-
-pub trait CargoPathExt {
- fn rm_rf(&self) -> io::Result<()>;
- fn mkdir_p(&self) -> io::Result<()>;
- fn move_into_the_past(&self) -> io::Result<()>;
-
- // cargo versions of the standard PathExt trait
- fn c_exists(&self) -> bool;
- fn c_is_file(&self) -> bool;
- fn c_is_dir(&self) -> bool;
- fn c_metadata(&self) -> io::Result<fs::Metadata>;
-}
-
-impl CargoPathExt for Path {
- /* Technically there is a potential race condition, but we don't
- * care all that much for our tests
- */
- fn rm_rf(&self) -> io::Result<()> {
- if self.c_exists() {
- for file in fs::read_dir(self).unwrap() {
- let file = try!(file).path();
-
- if file.c_is_dir() {
- try!(file.rm_rf());
- } else {
- // On windows we can't remove a readonly file, and git will
- // often clone files as readonly. As a result, we have some
- // special logic to remove readonly files on windows.
- match fs::remove_file(&file) {
- Ok(()) => {}
- Err(ref e) if cfg!(windows) &&
- e.kind() == ErrorKind::PermissionDenied => {
- let mut p = file.c_metadata().unwrap().permissions();
- p.set_readonly(false);
- fs::set_permissions(&file, p).unwrap();
- try!(fs::remove_file(&file));
- }
- Err(e) => return Err(e)
- }
- }
- }
- fs::remove_dir(self)
- } else {
- Ok(())
- }
- }
-
- fn mkdir_p(&self) -> io::Result<()> {
- fs::create_dir_all(self)
- }
-
- fn move_into_the_past(&self) -> io::Result<()> {
- if self.c_is_file() {
- try!(time_travel(self));
- } else {
- try!(recurse(self, &self.join("target")));
- }
- return Ok(());
-
- fn recurse(p: &Path, bad: &Path) -> io::Result<()> {
- if p.c_is_file() {
- time_travel(p)
- } else if p.starts_with(bad) {
- Ok(())
- } else {
- for f in try!(fs::read_dir(p)) {
- let f = try!(f).path();
- try!(recurse(&f, bad));
- }
- Ok(())
- }
- }
-
- fn time_travel(path: &Path) -> io::Result<()> {
- let stat = try!(path.c_metadata());
-
- let mtime = FileTime::from_last_modification_time(&stat);
- let newtime = mtime.seconds_relative_to_1970() - 3600;
- let nanos = mtime.nanoseconds();
- let newtime = FileTime::from_seconds_since_1970(newtime, nanos);
-
- // Sadly change_file_times has a failure mode where a readonly file
- // cannot have its times changed on windows.
- match filetime::set_file_times(path, newtime, newtime) {
- Err(ref e) if e.kind() == io::ErrorKind::PermissionDenied => {}
- e => return e,
- }
- let mut perms = stat.permissions();
- perms.set_readonly(false);
- try!(fs::set_permissions(path, perms));
- filetime::set_file_times(path, newtime, newtime)
- }
- }
-
- fn c_exists(&self) -> bool {
- fs::metadata(self).is_ok()
- }
-
- fn c_is_file(&self) -> bool {
- fs::metadata(self).map(|m| m.is_file()).unwrap_or(false)
- }
-
- fn c_is_dir(&self) -> bool {
- fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false)
- }
-
- fn c_metadata(&self) -> io::Result<fs::Metadata> {
- fs::metadata(self)
- }
-}
+++ /dev/null
-use std::collections::HashMap;
-use std::fs::{self, File};
-use std::io::prelude::*;
-use std::path::{PathBuf, Path};
-
-use flate2::Compression::Default;
-use flate2::write::GzEncoder;
-use git2;
-use rustc_serialize::hex::ToHex;
-use rustc_serialize::json::ToJson;
-use tar::{Builder, Header};
-use url::Url;
-
-use support::paths;
-use support::git::repo;
-use cargo::util::Sha256;
-
-pub fn registry_path() -> PathBuf { paths::root().join("registry") }
-pub fn registry() -> Url { Url::from_file_path(&*registry_path()).ok().unwrap() }
-pub fn dl_path() -> PathBuf { paths::root().join("dl") }
-pub fn dl_url() -> Url { Url::from_file_path(&*dl_path()).ok().unwrap() }
-
-pub struct Package {
- name: String,
- vers: String,
- deps: Vec<Dependency>,
- files: Vec<(String, String)>,
- yanked: bool,
- features: HashMap<String, Vec<String>>,
-}
-
-struct Dependency {
- name: String,
- vers: String,
- kind: String,
- target: Option<String>,
- features: Vec<String>,
-}
-
-fn init() {
- let config = paths::home().join(".cargo/config");
- fs::create_dir_all(config.parent().unwrap()).unwrap();
- if fs::metadata(&config).is_ok() {
- return
- }
- File::create(&config).unwrap().write_all(format!(r#"
- [registry]
- index = "{reg}"
- token = "api-token"
- "#, reg = registry()).as_bytes()).unwrap();
-
- // Init a new registry
- repo(®istry_path())
- .file("config.json", &format!(r#"
- {{"dl":"{}","api":""}}
- "#, dl_url()))
- .build();
-}
-
-impl Package {
- pub fn new(name: &str, vers: &str) -> Package {
- init();
- Package {
- name: name.to_string(),
- vers: vers.to_string(),
- deps: Vec::new(),
- files: Vec::new(),
- yanked: false,
- features: HashMap::new(),
- }
- }
-
- pub fn file(&mut self, name: &str, contents: &str) -> &mut Package {
- self.files.push((name.to_string(), contents.to_string()));
- self
- }
-
- pub fn dep(&mut self, name: &str, vers: &str) -> &mut Package {
- self.full_dep(name, vers, None, "normal", &[])
- }
-
- pub fn feature_dep(&mut self,
- name: &str,
- vers: &str,
- features: &[&str]) -> &mut Package {
- self.full_dep(name, vers, None, "normal", features)
- }
-
- pub fn target_dep(&mut self,
- name: &str,
- vers: &str,
- target: &str) -> &mut Package {
- self.full_dep(name, vers, Some(target), "normal", &[])
- }
-
- pub fn dev_dep(&mut self, name: &str, vers: &str) -> &mut Package {
- self.full_dep(name, vers, None, "dev", &[])
- }
-
- fn full_dep(&mut self,
- name: &str,
- vers: &str,
- target: Option<&str>,
- kind: &str,
- features: &[&str]) -> &mut Package {
- self.deps.push(Dependency {
- name: name.to_string(),
- vers: vers.to_string(),
- kind: kind.to_string(),
- target: target.map(|s| s.to_string()),
- features: features.iter().map(|s| s.to_string()).collect(),
- });
- self
- }
-
- pub fn yanked(&mut self, yanked: bool) -> &mut Package {
- self.yanked = yanked;
- self
- }
-
- pub fn publish(&self) {
- self.make_archive();
-
- // Figure out what we're going to write into the index
- let deps = self.deps.iter().map(|dep| {
- let mut map = HashMap::new();
- map.insert("name".to_string(), dep.name.to_json());
- map.insert("req".to_string(), dep.vers.to_json());
- map.insert("features".to_string(), dep.features.to_json());
- map.insert("default_features".to_string(), false.to_json());
- map.insert("target".to_string(), dep.target.to_json());
- map.insert("optional".to_string(), false.to_json());
- map.insert("kind".to_string(), dep.kind.to_json());
- map
- }).collect::<Vec<_>>();
- let cksum = {
- let mut c = Vec::new();
- File::open(&self.archive_dst()).unwrap()
- .read_to_end(&mut c).unwrap();
- cksum(&c)
- };
- let mut dep = HashMap::new();
- dep.insert("name".to_string(), self.name.to_json());
- dep.insert("vers".to_string(), self.vers.to_json());
- dep.insert("deps".to_string(), deps.to_json());
- dep.insert("cksum".to_string(), cksum.to_json());
- dep.insert("features".to_string(), self.features.to_json());
- dep.insert("yanked".to_string(), self.yanked.to_json());
- let line = dep.to_json().to_string();
-
- let file = match self.name.len() {
- 1 => format!("1/{}", self.name),
- 2 => format!("2/{}", self.name),
- 3 => format!("3/{}/{}", &self.name[..1], self.name),
- _ => format!("{}/{}/{}", &self.name[0..2], &self.name[2..4], self.name),
- };
-
- // Write file/line in the index
- let dst = registry_path().join(&file);
- let mut prev = String::new();
- let _ = File::open(&dst).and_then(|mut f| f.read_to_string(&mut prev));
- fs::create_dir_all(dst.parent().unwrap()).unwrap();
- File::create(&dst).unwrap()
- .write_all((prev + &line[..] + "\n").as_bytes()).unwrap();
-
- // Add the new file to the index
- let repo = git2::Repository::open(®istry_path()).unwrap();
- let mut index = repo.index().unwrap();
- index.add_path(Path::new(&file)).unwrap();
- index.write().unwrap();
- let id = index.write_tree().unwrap();
-
- // Commit this change
- let tree = repo.find_tree(id).unwrap();
- let sig = repo.signature().unwrap();
- let parent = repo.refname_to_id("refs/heads/master").unwrap();
- let parent = repo.find_commit(parent).unwrap();
- repo.commit(Some("HEAD"), &sig, &sig,
- "Another commit", &tree,
- &[&parent]).unwrap();
- }
-
- fn make_archive(&self) {
- let mut manifest = format!(r#"
- [package]
- name = "{}"
- version = "{}"
- authors = []
- "#, self.name, self.vers);
- for dep in self.deps.iter() {
- let target = match dep.target {
- None => String::new(),
- Some(ref s) => format!("target.{}.", s),
- };
- let kind = match &dep.kind[..] {
- "build" => "build-",
- "dev" => "dev-",
- _ => ""
- };
- manifest.push_str(&format!(r#"
- [{}{}dependencies.{}]
- version = "{}"
- "#, target, kind, dep.name, dep.vers));
- }
-
- let dst = self.archive_dst();
- fs::create_dir_all(dst.parent().unwrap()).unwrap();
- let f = File::create(&dst).unwrap();
- let mut a = Builder::new(GzEncoder::new(f, Default));
- self.append(&mut a, "Cargo.toml", &manifest);
- if self.files.is_empty() {
- self.append(&mut a, "src/lib.rs", "");
- } else {
- for &(ref name, ref contents) in self.files.iter() {
- self.append(&mut a, name, contents);
- }
- }
- }
-
- fn append<W: Write>(&self, ar: &mut Builder<W>, file: &str, contents: &str) {
- let mut header = Header::new_ustar();
- header.set_size(contents.len() as u64);
- header.set_path(format!("{}-{}/{}", self.name, self.vers, file)).unwrap();
- header.set_cksum();
-
- ar.append(&header, contents.as_bytes()).unwrap();
- }
-
- pub fn archive_dst(&self) -> PathBuf {
- dl_path().join(&self.name).join(&self.vers).join("download")
- }
-}
-
-fn cksum(s: &[u8]) -> String {
- let mut sha = Sha256::new();
- sha.update(s);
- sha.finish().to_hex()
-}
--- /dev/null
+extern crate cargo;
+extern crate cargotest;
+extern crate hamcrest;
+
+use std::fs::File;
+use std::io::prelude::*;
+use std::str;
+
+use cargotest::{sleep_ms, is_nightly};
+use cargotest::support::{project, execs, basic_bin_manifest, basic_lib_manifest};
+use cargotest::support::paths::CargoPathExt;
+use hamcrest::{assert_that, existing_file, is_not};
+use cargo::util::process;
+
+#[test]
+fn cargo_test_simple() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", r#"
+ fn hello() -> &'static str {
+ "hello"
+ }
+
+ pub fn main() {
+ println!("{}", hello())
+ }
+
+ #[test]
+ fn test_hello() {
+ assert_eq!(hello(), "hello")
+ }"#);
+
+ assert_that(p.cargo_process("build"), execs());
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("hello\n"));
+
+ assert_that(p.cargo("test"),
+ execs().with_stderr(format!("\
+[COMPILING] foo v0.5.0 ({})
+[RUNNING] target[..]foo-[..]", p.url()))
+ .with_stdout("
+running 1 test
+test test_hello ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn cargo_test_release() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.1.0"
+
+ [dependencies]
+ bar = { path = "bar" }
+ "#)
+ .file("src/lib.rs", r#"
+ extern crate bar;
+ pub fn foo() { bar::bar(); }
+
+ #[test]
+ fn test() { foo(); }
+ "#)
+ .file("tests/test.rs", r#"
+ extern crate foo;
+
+ #[test]
+ fn test() { foo::foo(); }
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "pub fn bar() {}");
+
+ assert_that(p.cargo_process("test").arg("-v").arg("--release"),
+ execs().with_stderr(format!("\
+[COMPILING] bar v0.0.1 ({dir}/bar)
+[RUNNING] [..] -C opt-level=3 [..]
+[COMPILING] foo v0.1.0 ({dir})
+[RUNNING] [..] -C opt-level=3 [..]
+[RUNNING] [..] -C opt-level=3 [..]
+[RUNNING] [..] -C opt-level=3 [..]
+[RUNNING] `[..]target[..]foo-[..]`
+[RUNNING] `[..]target[..]test-[..]`
+[DOCTEST] foo
+[RUNNING] `rustdoc --test [..]lib.rs[..]`", dir = p.url()))
+ .with_stdout("
+running 1 test
+test test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn cargo_test_verbose() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", r#"
+ fn main() {}
+ #[test] fn test_hello() {}
+ "#);
+
+ assert_that(p.cargo_process("test").arg("-v").arg("hello"),
+ execs().with_stderr(format!("\
+[COMPILING] foo v0.5.0 ({url})
+[RUNNING] `rustc src[..]foo.rs [..]`
+[RUNNING] `[..]target[..]foo-[..] hello`", url = p.url()))
+ .with_stdout("
+running 1 test
+test test_hello ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn many_similar_names() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "
+ pub fn foo() {}
+ #[test] fn lib_test() {}
+ ")
+ .file("src/main.rs", "
+ extern crate foo;
+ fn main() {}
+ #[test] fn bin_test() { foo::foo() }
+ ")
+ .file("tests/foo.rs", r#"
+ extern crate foo;
+ #[test] fn test_test() { foo::foo() }
+ "#);
+
+ let output = p.cargo_process("test").arg("-v").exec_with_output().unwrap();
+ let output = str::from_utf8(&output.stdout).unwrap();
+ assert!(output.contains("test bin_test"), "bin_test missing\n{}", output);
+ assert!(output.contains("test lib_test"), "lib_test missing\n{}", output);
+ assert!(output.contains("test test_test"), "test_test missing\n{}", output);
+}
+
+#[test]
+fn cargo_test_failing_test() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", r#"
+ fn hello() -> &'static str {
+ "hello"
+ }
+
+ pub fn main() {
+ println!("{}", hello())
+ }
+
+ #[test]
+ fn test_hello() {
+ assert_eq!(hello(), "nope")
+ }"#);
+
+ assert_that(p.cargo_process("build"), execs());
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(process(&p.bin("foo")),
+ execs().with_stdout("hello\n"));
+
+ assert_that(p.cargo("test"),
+ execs().with_stderr(format!("\
+[COMPILING] foo v0.5.0 ({url})
+[RUNNING] target[..]foo-[..]
+[ERROR] test failed", url = p.url()))
+ .with_stdout_contains("
+running 1 test
+test test_hello ... FAILED
+
+failures:
+
+---- test_hello stdout ----
+<tab>thread 'test_hello' panicked at 'assertion failed: \
+ `(left == right)` (left: \
+ `\"hello\"`, right: `\"nope\"`)', src[..]foo.rs:12
+")
+ .with_stdout_contains("\
+failures:
+ test_hello
+
+test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
+")
+ .with_status(101));
+}
+
+#[test]
+fn test_with_lib_dep() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [[bin]]
+ name = "baz"
+ path = "src/main.rs"
+ "#)
+ .file("src/lib.rs", r#"
+ ///
+ /// ```rust
+ /// extern crate foo;
+ /// fn main() {
+ /// println!("{:?}", foo::foo());
+ /// }
+ /// ```
+ ///
+ pub fn foo(){}
+ #[test] fn lib_test() {}
+ "#)
+ .file("src/main.rs", "
+ extern crate foo;
+
+ fn main() {}
+
+ #[test]
+ fn bin_test() {}
+ ");
+
+ assert_that(p.cargo_process("test"),
+ execs().with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({})
+[RUNNING] target[..]baz-[..]
+[RUNNING] target[..]foo[..]
+[DOCTEST] foo", p.url()))
+ .with_stdout("
+running 1 test
+test bin_test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test lib_test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test foo_0 ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"))
+}
+
+#[test]
+fn test_with_deep_lib_dep() {
+ let p = project("bar")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.foo]
+ path = "../foo"
+ "#)
+ .file("src/lib.rs", "
+ extern crate foo;
+ /// ```
+ /// bar::bar();
+ /// ```
+ pub fn bar() {}
+
+ #[test]
+ fn bar_test() {
+ foo::foo();
+ }
+ ");
+ let p2 = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "
+ pub fn foo() {}
+
+ #[test]
+ fn foo_test() {}
+ ");
+
+ p2.build();
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ([..])
+[COMPILING] bar v0.0.1 ({dir})
+[RUNNING] target[..]
+[DOCTEST] bar", dir = p.url()))
+ .with_stdout("
+running 1 test
+test bar_test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test bar_0 ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn external_test_explicit() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [[test]]
+ name = "test"
+ path = "src/test.rs"
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn get_hello() -> &'static str { "Hello" }
+
+ #[test]
+ fn internal_test() {}
+ "#)
+ .file("src/test.rs", r#"
+ extern crate foo;
+
+ #[test]
+ fn external_test() { assert_eq!(foo::get_hello(), "Hello") }
+ "#);
+
+ assert_that(p.cargo_process("test"),
+ execs().with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({})
+[RUNNING] target[..]foo-[..]
+[RUNNING] target[..]test-[..]
+[DOCTEST] foo", p.url()))
+ .with_stdout("
+running 1 test
+test internal_test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test external_test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"))
+}
+
+#[test]
+fn external_test_implicit() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn get_hello() -> &'static str { "Hello" }
+
+ #[test]
+ fn internal_test() {}
+ "#)
+ .file("tests/external.rs", r#"
+ extern crate foo;
+
+ #[test]
+ fn external_test() { assert_eq!(foo::get_hello(), "Hello") }
+ "#);
+
+ assert_that(p.cargo_process("test"),
+ execs().with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({})
+[RUNNING] target[..]external-[..]
+[RUNNING] target[..]foo-[..]
+[DOCTEST] foo", p.url()))
+ .with_stdout("
+running 1 test
+test external_test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test internal_test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"))
+}
+
+#[test]
+fn dont_run_examples() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ "#)
+ .file("examples/dont-run-me-i-will-fail.rs", r#"
+ fn main() { panic!("Examples should not be run by 'cargo test'"); }
+ "#);
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0));
+}
+
+#[test]
+fn pass_through_command_line() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "
+ #[test] fn foo() {}
+ #[test] fn bar() {}
+ ");
+
+ assert_that(p.cargo_process("test").arg("bar"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] target[..]foo-[..]
+[DOCTEST] foo", dir = p.url()))
+ .with_stdout("
+running 1 test
+test bar ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+
+ assert_that(p.cargo("test").arg("foo"),
+ execs().with_status(0)
+ .with_stderr("\
+[RUNNING] target[..]foo-[..]
+[DOCTEST] foo")
+ .with_stdout("
+running 1 test
+test foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+// Regression test for running cargo-test twice with
+// tests in an rlib
+#[test]
+fn cargo_test_twice() {
+ let p = project("test_twice")
+ .file("Cargo.toml", &basic_lib_manifest("test_twice"))
+ .file("src/test_twice.rs", r#"
+ #![crate_type = "rlib"]
+
+ #[test]
+ fn dummy_test() { }
+ "#);
+
+ p.cargo_process("build");
+
+ for _ in 0..2 {
+ assert_that(p.cargo("test"),
+ execs().with_status(0));
+ }
+}
+
+#[test]
+fn lib_bin_same_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo"
+ [[bin]]
+ name = "foo"
+ "#)
+ .file("src/lib.rs", "
+ #[test] fn lib_test() {}
+ ")
+ .file("src/main.rs", "
+ extern crate foo;
+
+ #[test]
+ fn bin_test() {}
+ ");
+
+ assert_that(p.cargo_process("test"),
+ execs().with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({})
+[RUNNING] target[..]foo-[..]
+[RUNNING] target[..]foo-[..]
+[DOCTEST] foo", p.url()))
+ .with_stdout("
+running 1 test
+test [..] ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test [..] ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"))
+}
+
+#[test]
+fn lib_with_standard_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "syntax"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "
+ /// ```
+ /// syntax::foo();
+ /// ```
+ pub fn foo() {}
+
+ #[test]
+ fn foo_test() {}
+ ")
+ .file("tests/test.rs", "
+ extern crate syntax;
+
+ #[test]
+ fn test() { syntax::foo() }
+ ");
+
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] syntax v0.0.1 ({dir})
+[RUNNING] target[..]syntax-[..]
+[RUNNING] target[..]test-[..]
+[DOCTEST] syntax", dir = p.url()))
+ .with_stdout("
+running 1 test
+test foo_test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test foo_0 ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn lib_with_standard_name2() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "syntax"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "syntax"
+ test = false
+ doctest = false
+ "#)
+ .file("src/lib.rs", "
+ pub fn foo() {}
+ ")
+ .file("src/main.rs", "
+ extern crate syntax;
+
+ fn main() {}
+
+ #[test]
+ fn test() { syntax::foo() }
+ ");
+
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] syntax v0.0.1 ({dir})
+[RUNNING] target[..]syntax-[..]", dir = p.url()))
+ .with_stdout("
+running 1 test
+test test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn lib_without_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "syntax"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ test = false
+ doctest = false
+ "#)
+ .file("src/lib.rs", "
+ pub fn foo() {}
+ ")
+ .file("src/main.rs", "
+ extern crate syntax;
+
+ fn main() {}
+
+ #[test]
+ fn test() { syntax::foo() }
+ ");
+
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] syntax v0.0.1 ({dir})
+[RUNNING] target[..]syntax-[..]", dir = p.url()))
+ .with_stdout("
+running 1 test
+test test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn bin_without_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "syntax"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ test = false
+ doctest = false
+
+ [[bin]]
+ path = "src/main.rs"
+ "#)
+ .file("src/lib.rs", "
+ pub fn foo() {}
+ ")
+ .file("src/main.rs", "
+ extern crate syntax;
+
+ fn main() {}
+
+ #[test]
+ fn test() { syntax::foo() }
+ ");
+
+ assert_that(p.cargo_process("test"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ binary target bin.name is required"));
+}
+
+#[test]
+fn bench_without_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "syntax"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ test = false
+ doctest = false
+
+ [[bench]]
+ path = "src/bench.rs"
+ "#)
+ .file("src/lib.rs", "
+ pub fn foo() {}
+ ")
+ .file("src/main.rs", "
+ extern crate syntax;
+
+ fn main() {}
+
+ #[test]
+ fn test() { syntax::foo() }
+ ")
+ .file("src/bench.rs", "
+ #![feature(test)]
+ extern crate syntax;
+ extern crate test;
+
+ #[bench]
+ fn external_bench(_b: &mut test::Bencher) {}
+ ");
+
+ assert_that(p.cargo_process("test"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ bench target bench.name is required"));
+}
+
+#[test]
+fn test_without_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "syntax"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ test = false
+ doctest = false
+
+ [[test]]
+ path = "src/test.rs"
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn foo() {}
+ pub fn get_hello() -> &'static str { "Hello" }
+ "#)
+ .file("src/main.rs", "
+ extern crate syntax;
+
+ fn main() {}
+
+ #[test]
+ fn test() { syntax::foo() }
+ ")
+ .file("src/test.rs", r#"
+ extern crate syntax;
+
+ #[test]
+ fn external_test() { assert_eq!(syntax::get_hello(), "Hello") }
+ "#);
+
+ assert_that(p.cargo_process("test"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ test target test.name is required"));
+}
+
+#[test]
+fn example_without_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "syntax"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ test = false
+ doctest = false
+
+ [[example]]
+ path = "examples/example.rs"
+ "#)
+ .file("src/lib.rs", "
+ pub fn foo() {}
+ ")
+ .file("src/main.rs", "
+ extern crate syntax;
+
+ fn main() {}
+
+ #[test]
+ fn test() { syntax::foo() }
+ ")
+ .file("examples/example.rs", r#"
+ extern crate syntax;
+
+ fn main() {
+ println!("example1");
+ }
+ "#);
+
+ assert_that(p.cargo_process("test"),
+ execs().with_status(101)
+ .with_stderr("\
+[ERROR] failed to parse manifest at `[..]`
+
+Caused by:
+ example target example.name is required"));
+}
+
+#[test]
+fn bin_there_for_integration() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", "
+ fn main() { std::process::exit(101); }
+ #[test] fn main_test() {}
+ ")
+ .file("tests/foo.rs", r#"
+ use std::process::Command;
+ #[test]
+ fn test_test() {
+ let status = Command::new("target/debug/foo").status().unwrap();
+ assert_eq!(status.code(), Some(101));
+ }
+ "#);
+
+ let output = p.cargo_process("test").arg("-v").exec_with_output().unwrap();
+ let output = str::from_utf8(&output.stdout).unwrap();
+ assert!(output.contains("main_test ... ok"), "no main_test\n{}", output);
+ assert!(output.contains("test_test ... ok"), "no test_test\n{}", output);
+}
+
+#[test]
+fn test_dylib() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo"
+ crate_type = ["dylib"]
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/lib.rs", r#"
+ extern crate bar as the_bar;
+
+ pub fn bar() { the_bar::baz(); }
+
+ #[test]
+ fn foo() { bar(); }
+ "#)
+ .file("tests/test.rs", r#"
+ extern crate foo as the_foo;
+
+ #[test]
+ fn foo() { the_foo::bar(); }
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "bar"
+ crate_type = ["dylib"]
+ "#)
+ .file("bar/src/lib.rs", "
+ pub fn baz() {}
+ ");
+
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] bar v0.0.1 ({dir}/bar)
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] target[..]foo-[..]
+[RUNNING] target[..]test-[..]", dir = p.url()))
+ .with_stdout("
+running 1 test
+test foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+ p.root().move_into_the_past();
+ assert_that(p.cargo("test"),
+ execs().with_status(0)
+ .with_stderr("\
+[RUNNING] target[..]foo-[..]
+[RUNNING] target[..]test-[..]")
+ .with_stdout("
+running 1 test
+test foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+
+}
+
+#[test]
+fn test_twice_with_build_cmd() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("build.rs", "fn main() {}")
+ .file("src/lib.rs", "
+ #[test]
+ fn foo() {}
+ ");
+
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] target[..]foo-[..]
+[DOCTEST] foo", dir = p.url()))
+ .with_stdout("
+running 1 test
+test foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+
+ assert_that(p.cargo("test"),
+ execs().with_status(0)
+ .with_stderr("\
+[RUNNING] target[..]foo-[..]
+[DOCTEST] foo")
+ .with_stdout("
+running 1 test
+test foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn test_then_build() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "
+ #[test]
+ fn foo() {}
+ ");
+
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] target[..]foo-[..]
+[DOCTEST] foo", dir = p.url()))
+ .with_stdout("
+running 1 test
+test foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0)
+ .with_stdout(""));
+}
+
+#[test]
+fn test_no_run() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "
+ #[test]
+ fn foo() { panic!() }
+ ");
+
+ assert_that(p.cargo_process("test").arg("--no-run"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+",
+ dir = p.url())));
+}
+
+#[test]
+fn test_run_specific_bin_target() {
+ let prj = project("foo")
+ .file("Cargo.toml" , r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [[bin]]
+ name="bin1"
+ path="src/bin1.rs"
+
+ [[bin]]
+ name="bin2"
+ path="src/bin2.rs"
+ "#)
+ .file("src/bin1.rs", "#[test] fn test1() { }")
+ .file("src/bin2.rs", "#[test] fn test2() { }");
+
+ assert_that(prj.cargo_process("test").arg("--bin").arg("bin2"),
+ execs().with_status(0)
+ .with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] target[..]bin2-[..]", dir = prj.url()))
+ .with_stdout("
+running 1 test
+test test2 ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn test_run_specific_test_target() {
+ let prj = project("foo")
+ .file("Cargo.toml" , r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/bin/a.rs", "fn main() { }")
+ .file("src/bin/b.rs", "#[test] fn test_b() { } fn main() { }")
+ .file("tests/a.rs", "#[test] fn test_a() { }")
+ .file("tests/b.rs", "#[test] fn test_b() { }");
+
+ assert_that(prj.cargo_process("test").arg("--test").arg("b"),
+ execs().with_status(0)
+ .with_stderr(format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] target[..]b-[..]", dir = prj.url()))
+ .with_stdout("
+running 1 test
+test test_b ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn test_no_harness() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [[bin]]
+ name = "foo"
+ test = false
+
+ [[test]]
+ name = "bar"
+ path = "foo.rs"
+ harness = false
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("foo.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("test").arg("--").arg("--nocapture"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] target[..]bar-[..]
+",
+ dir = p.url())));
+}
+
+#[test]
+fn selective_testing() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.d1]
+ path = "d1"
+ [dependencies.d2]
+ path = "d2"
+
+ [lib]
+ name = "foo"
+ doctest = false
+ "#)
+ .file("src/lib.rs", "")
+ .file("d1/Cargo.toml", r#"
+ [package]
+ name = "d1"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "d1"
+ doctest = false
+ "#)
+ .file("d1/src/lib.rs", "")
+ .file("d1/src/main.rs", "extern crate d1; fn main() {}")
+ .file("d2/Cargo.toml", r#"
+ [package]
+ name = "d2"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "d2"
+ doctest = false
+ "#)
+ .file("d2/src/lib.rs", "")
+ .file("d2/src/main.rs", "extern crate d2; fn main() {}");
+ p.build();
+
+ println!("d1");
+ assert_that(p.cargo("test").arg("-p").arg("d1"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] d1 v0.0.1 ({dir}/d1)
+[RUNNING] target[..]d1-[..]
+[RUNNING] target[..]d1-[..]", dir = p.url()))
+ .with_stdout("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+
+ println!("d2");
+ assert_that(p.cargo("test").arg("-p").arg("d2"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] d2 v0.0.1 ({dir}/d2)
+[RUNNING] target[..]d2-[..]
+[RUNNING] target[..]d2-[..]", dir = p.url()))
+ .with_stdout("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+
+ println!("whole");
+ assert_that(p.cargo("test"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] target[..]foo-[..]", dir = p.url()))
+ .with_stdout("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn almost_cyclic_but_not_quite() {
+ let p = project("a")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [dev-dependencies.b]
+ path = "b"
+ [dev-dependencies.c]
+ path = "c"
+ "#)
+ .file("src/lib.rs", r#"
+ #[cfg(test)] extern crate b;
+ #[cfg(test)] extern crate c;
+ "#)
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.a]
+ path = ".."
+ "#)
+ .file("b/src/lib.rs", r#"
+ extern crate a;
+ "#)
+ .file("c/Cargo.toml", r#"
+ [package]
+ name = "c"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("c/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+ assert_that(p.cargo("test"),
+ execs().with_status(0));
+}
+
+#[test]
+fn build_then_selective_test() {
+ let p = project("a")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.b]
+ path = "b"
+ "#)
+ .file("src/lib.rs", "extern crate b;")
+ .file("src/main.rs", "extern crate b; extern crate a; fn main() {}")
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("b/src/lib.rs", "");
+
+ assert_that(p.cargo_process("build"), execs().with_status(0));
+ p.root().move_into_the_past();
+ assert_that(p.cargo("test").arg("-p").arg("b"),
+ execs().with_status(0));
+}
+
+#[test]
+fn example_dev_dep() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dev-dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/lib.rs", r#"
+ "#)
+ .file("examples/e1.rs", r#"
+ extern crate bar;
+ fn main() { }
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", r#"
+ // make sure this file takes awhile to compile
+ macro_rules! f0( () => (1) );
+ macro_rules! f1( () => ({(f0!()) + (f0!())}) );
+ macro_rules! f2( () => ({(f1!()) + (f1!())}) );
+ macro_rules! f3( () => ({(f2!()) + (f2!())}) );
+ macro_rules! f4( () => ({(f3!()) + (f3!())}) );
+ macro_rules! f5( () => ({(f4!()) + (f4!())}) );
+ macro_rules! f6( () => ({(f5!()) + (f5!())}) );
+ macro_rules! f7( () => ({(f6!()) + (f6!())}) );
+ macro_rules! f8( () => ({(f7!()) + (f7!())}) );
+ pub fn bar() {
+ f8!();
+ }
+ "#);
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0));
+ assert_that(p.cargo("run")
+ .arg("--example").arg("e1").arg("--release").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn selective_testing_with_docs() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.d1]
+ path = "d1"
+ "#)
+ .file("src/lib.rs", r#"
+ /// ```
+ /// not valid rust
+ /// ```
+ pub fn foo() {}
+ "#)
+ .file("d1/Cargo.toml", r#"
+ [package]
+ name = "d1"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "d1"
+ path = "d1.rs"
+ "#)
+ .file("d1/d1.rs", "");
+ p.build();
+
+ assert_that(p.cargo("test").arg("-p").arg("d1"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] d1 v0.0.1 ({dir}/d1)
+[RUNNING] target[..]deps[..]d1[..]
+[DOCTEST] d1", dir = p.url()))
+ .with_stdout("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn example_bin_same_name() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/bin/foo.rs", r#"fn main() { println!("bin"); }"#)
+ .file("examples/foo.rs", r#"fn main() { println!("example"); }"#);
+
+ assert_that(p.cargo_process("test").arg("--no-run").arg("-v"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({dir})
+[RUNNING] `rustc [..]`
+[RUNNING] `rustc [..]`
+", dir = p.url())));
+
+ assert_that(&p.bin("foo"), is_not(existing_file()));
+ assert_that(&p.bin("examples/foo"), existing_file());
+
+ assert_that(p.process(&p.bin("examples/foo")),
+ execs().with_status(0).with_stdout("example\n"));
+
+ assert_that(p.cargo("run"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] [..]")
+ .with_stdout("\
+bin
+"));
+ assert_that(&p.bin("foo"), existing_file());
+}
+
+#[test]
+fn test_with_example_twice() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/bin/foo.rs", r#"fn main() { println!("bin"); }"#)
+ .file("examples/foo.rs", r#"fn main() { println!("example"); }"#);
+
+ println!("first");
+ assert_that(p.cargo_process("test").arg("-v"),
+ execs().with_status(0));
+ assert_that(&p.bin("examples/foo"), existing_file());
+ println!("second");
+ assert_that(p.cargo("test").arg("-v"),
+ execs().with_status(0));
+ assert_that(&p.bin("examples/foo"), existing_file());
+}
+
+#[test]
+fn example_with_dev_dep() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo"
+ test = false
+ doctest = false
+
+ [dev-dependencies.a]
+ path = "a"
+ "#)
+ .file("src/lib.rs", "")
+ .file("examples/ex.rs", "extern crate a; fn main() {}")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "");
+
+ assert_that(p.cargo_process("test").arg("-v"),
+ execs().with_status(0)
+ .with_stderr("\
+[..]
+[..]
+[..]
+[..]
+[RUNNING] `rustc [..] --crate-name ex [..] --extern a=[..]`
+"));
+}
+
+#[test]
+fn bin_is_preserved() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+ assert_that(&p.bin("foo"), existing_file());
+
+ println!("testing");
+ assert_that(p.cargo("test").arg("-v"),
+ execs().with_status(0));
+ assert_that(&p.bin("foo"), existing_file());
+}
+
+#[test]
+fn bad_example() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "");
+
+ assert_that(p.cargo_process("run").arg("--example").arg("foo"),
+ execs().with_status(101).with_stderr("\
+[ERROR] no example target named `foo`
+"));
+ assert_that(p.cargo_process("run").arg("--bin").arg("foo"),
+ execs().with_status(101).with_stderr("\
+[ERROR] no bin target named `foo`
+"));
+}
+
+#[test]
+fn doctest_feature() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ [features]
+ bar = []
+ "#)
+ .file("src/lib.rs", r#"
+ /// ```rust
+ /// assert_eq!(foo::foo(), 1);
+ /// ```
+ #[cfg(feature = "bar")]
+ pub fn foo() -> i32 { 1 }
+ "#);
+
+ assert_that(p.cargo_process("test").arg("--features").arg("bar"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] foo [..]
+[RUNNING] target[..]foo[..]
+[DOCTEST] foo")
+ .with_stdout("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test foo_0 ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"))
+}
+
+#[test]
+fn dashes_to_underscores() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo-bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ /// ```
+ /// assert_eq!(foo_bar::foo(), 1);
+ /// ```
+ pub fn foo() -> i32 { 1 }
+ "#);
+
+ assert_that(p.cargo_process("test").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn doctest_dev_dep() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dev-dependencies]
+ b = { path = "b" }
+ "#)
+ .file("src/lib.rs", r#"
+ /// ```
+ /// extern crate b;
+ /// ```
+ pub fn foo() {}
+ "#)
+ .file("b/Cargo.toml", r#"
+ [package]
+ name = "b"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("b/src/lib.rs", "");
+
+ assert_that(p.cargo_process("test").arg("-v"),
+ execs().with_status(0));
+}
+
+#[test]
+fn filter_no_doc_tests() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ /// ```
+ /// extern crate b;
+ /// ```
+ pub fn foo() {}
+ "#)
+ .file("tests/foo.rs", "");
+
+ assert_that(p.cargo_process("test").arg("--test=foo"),
+ execs().with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] target[..]debug[..]foo[..]")
+ .with_stdout("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn dylib_doctest() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo"
+ crate-type = ["rlib", "dylib"]
+ test = false
+ "#)
+ .file("src/lib.rs", r#"
+ /// ```
+ /// foo::foo();
+ /// ```
+ pub fn foo() {}
+ "#);
+
+ assert_that(p.cargo_process("test"),
+ execs().with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[DOCTEST] foo")
+ .with_stdout("
+running 1 test
+test foo_0 ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+}
+
+#[test]
+fn dylib_doctest2() {
+ // can't doctest dylibs as they're statically linked together
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo"
+ crate-type = ["dylib"]
+ test = false
+ "#)
+ .file("src/lib.rs", r#"
+ /// ```
+ /// foo::foo();
+ /// ```
+ pub fn foo() {}
+ "#);
+
+ assert_that(p.cargo_process("test"),
+ execs().with_stdout(""));
+}
+
+#[test]
+fn cyclic_dev_dep_doc_test() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dev-dependencies]
+ bar = { path = "bar" }
+ "#)
+ .file("src/lib.rs", r#"
+ //! ```
+ //! extern crate bar;
+ //! ```
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ foo = { path = ".." }
+ "#)
+ .file("bar/src/lib.rs", r#"
+ extern crate foo;
+ "#);
+ assert_that(p.cargo_process("test"),
+ execs().with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[COMPILING] bar v0.0.1 ([..])
+[RUNNING] target[..]foo[..]
+[DOCTEST] foo")
+ .with_stdout("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test _0 ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"))
+}
+
+#[test]
+fn dev_dep_with_build_script() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dev-dependencies]
+ bar = { path = "bar" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("examples/foo.rs", "fn main() {}")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("bar/src/lib.rs", "")
+ .file("bar/build.rs", "fn main() {}");
+ assert_that(p.cargo_process("test"),
+ execs().with_status(0));
+}
+
+#[test]
+fn no_fail_fast() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ pub fn add_one(x: i32) -> i32{
+ x + 1
+ }
+
+ /// ```rust
+ /// use foo::sub_one;
+ /// assert_eq!(sub_one(101), 100);
+ /// ```
+ pub fn sub_one(x: i32) -> i32{
+ x - 1
+ }
+ "#)
+ .file("tests/test_add_one.rs", r#"
+ extern crate foo;
+ use foo::*;
+
+ #[test]
+ fn add_one_test() {
+ assert_eq!(add_one(1), 2);
+ }
+
+ #[test]
+ fn fail_add_one_test() {
+ assert_eq!(add_one(1), 1);
+ }
+ "#)
+ .file("tests/test_sub_one.rs", r#"
+ extern crate foo;
+ use foo::*;
+
+ #[test]
+ fn sub_one_test() {
+ assert_eq!(sub_one(1), 0);
+ }
+ "#);
+ assert_that(p.cargo_process("test").arg("--no-fail-fast"),
+ execs().with_status(101)
+ .with_stderr_contains("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] target[..]foo[..]
+[RUNNING] target[..]test_add_one[..]")
+ .with_stdout_contains("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+")
+ .with_stderr_contains("\
+[RUNNING] target[..]test_sub_one[..]
+[DOCTEST] foo")
+ .with_stdout_contains("\
+test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test sub_one_test ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test sub_one_0 ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"))
+}
+
+#[test]
+fn test_multiple_packages() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.d1]
+ path = "d1"
+ [dependencies.d2]
+ path = "d2"
+
+ [lib]
+ name = "foo"
+ doctest = false
+ "#)
+ .file("src/lib.rs", "")
+ .file("d1/Cargo.toml", r#"
+ [package]
+ name = "d1"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "d1"
+ doctest = false
+ "#)
+ .file("d1/src/lib.rs", "")
+ .file("d2/Cargo.toml", r#"
+ [package]
+ name = "d2"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "d2"
+ doctest = false
+ "#)
+ .file("d2/src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo("test").arg("-p").arg("d1").arg("-p").arg("d2"),
+ execs().with_status(0)
+ .with_stderr_contains("\
+[RUNNING] target[..]debug[..]d1-[..]")
+ .with_stdout_contains("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+")
+ .with_stderr_contains("\
+[RUNNING] target[..]debug[..]d2-[..]")
+ .with_stdout_contains("
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+"));
+}
+
+#[test]
+fn bin_does_not_rebuild_tests() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/main.rs", "fn main() {}")
+ .file("tests/foo.rs", "");
+ p.build();
+
+ assert_that(p.cargo("test").arg("-v"),
+ execs().with_status(0));
+
+ sleep_ms(1000);
+ File::create(&p.root().join("src/main.rs")).unwrap()
+ .write_all(b"fn main() { 3; }").unwrap();
+
+ assert_that(p.cargo("test").arg("-v").arg("--no-run"),
+ execs().with_status(0)
+ .with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc src[..]main.rs [..]`
+[RUNNING] `rustc src[..]main.rs [..]`
+"));
+}
+
+#[test]
+fn selective_test_wonky_profile() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [profile.release]
+ opt-level = 2
+
+ [dependencies]
+ a = { path = "a" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo("test").arg("-v").arg("--no-run").arg("--release")
+ .arg("-p").arg("foo").arg("-p").arg("a"),
+ execs().with_status(0));
+}
+
+#[test]
+fn selective_test_optional_dep() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ a = { path = "a", optional = true }
+ "#)
+ .file("src/lib.rs", "")
+ .file("a/Cargo.toml", r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("a/src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo("test").arg("-v").arg("--no-run")
+ .arg("--features").arg("a").arg("-p").arg("a"),
+ execs().with_status(0).with_stderr("\
+[COMPILING] a v0.0.1 ([..])
+[RUNNING] `rustc a[..]src[..]lib.rs [..]`
+[RUNNING] `rustc a[..]src[..]lib.rs [..]`
+"));
+}
+
+#[test]
+fn only_test_docs() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", r#"
+ #[test]
+ fn foo() {
+ let a: u32 = "hello";
+ }
+
+ /// ```
+ /// println!("ok");
+ /// ```
+ pub fn bar() {
+ }
+ "#)
+ .file("tests/foo.rs", "this is not rust");
+ p.build();
+
+ assert_that(p.cargo("test").arg("--doc"),
+ execs().with_status(0)
+ .with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ([..])
+[DOCTEST] foo"))
+ .with_stdout("
+running 1 test
+test bar_0 ... ok
+
+test result: ok.[..]
+
+"));
+}
+
+#[test]
+fn test_panic_abort_with_dep() {
+ if !is_nightly() {
+ return
+ }
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = { path = "bar" }
+
+ [profile.dev]
+ panic = 'abort'
+ "#)
+ .file("src/lib.rs", r#"
+ extern crate bar;
+
+ #[test]
+ fn foo() {}
+ "#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("bar/src/lib.rs", "");
+ assert_that(p.cargo_process("test").arg("-v"),
+ execs().with_status(0));
+}
+++ /dev/null
-use support::{project, execs};
-use support::registry::Package;
-use hamcrest::assert_that;
-
-#[test]
-fn bad1() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", r#"
- [target]
- nonexistent-target = "foo"
- "#);
- assert_that(foo.cargo_process("build").arg("-v")
- .arg("--target=nonexistent-target"),
- execs().with_status(101).with_stderr("\
-[ERROR] expected table for configuration key `target.nonexistent-target`, \
-but found string in [..]config
-"));
-}
-
-#[test]
-fn bad2() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", r#"
- [http]
- proxy = 3.0
- "#);
- assert_that(foo.cargo_process("publish").arg("-v"),
- execs().with_status(101).with_stderr("\
-[ERROR] Couldn't load Cargo configuration
-
-Caused by:
- failed to load TOML configuration from `[..]config`
-
-Caused by:
- failed to parse key `http`
-
-Caused by:
- failed to parse key `proxy`
-
-Caused by:
- found TOML configuration value of unknown type `float`
-"));
-}
-
-#[test]
-fn bad3() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", r#"
- [http]
- proxy = true
- "#);
- assert_that(foo.cargo_process("publish").arg("-v"),
- execs().with_status(101).with_stderr("\
-[UPDATING] registry `https://[..]`
-[ERROR] invalid configuration for key `http.proxy`
-expected a string, but found a boolean in [..]config
-"));
-}
-
-#[test]
-fn bad4() {
- let foo = project("foo")
- .file(".cargo/config", r#"
- [cargo-new]
- name = false
- "#);
- assert_that(foo.cargo_process("new").arg("-v").arg("foo"),
- execs().with_status(101).with_stderr("\
-[ERROR] Failed to create project `foo` at `[..]`
-
-Caused by:
- invalid configuration for key `cargo-new.name`
-expected a string, but found a boolean in [..]config
-"));
-}
-
-#[test]
-fn bad5() {
- let foo = project("foo")
- .file(".cargo/config", r#"
- foo = ""
- "#)
- .file("foo/.cargo/config", r#"
- foo = 2
- "#);
- foo.build();
- assert_that(foo.cargo("new")
- .arg("-v").arg("foo").cwd(&foo.root().join("foo")),
- execs().with_status(101).with_stderr("\
-[ERROR] Couldn't load Cargo configuration
-
-Caused by:
- failed to merge key `foo` between files:
- file 1: [..]foo[..]foo[..]config
- file 2: [..]foo[..]config
-
-Caused by:
- expected integer, but found string
-"));
-}
-
-#[test]
-fn bad_cargo_config_jobs() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", r#"
- [build]
- jobs = -1
- "#);
- assert_that(foo.cargo_process("build").arg("-v"),
- execs().with_status(101).with_stderr("\
-[ERROR] build.jobs must be positive, but found -1 in [..]
-"));
-}
-
-#[test]
-fn default_cargo_config_jobs() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", r#"
- [build]
- jobs = 1
- "#);
- assert_that(foo.cargo_process("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn good_cargo_config_jobs() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", r#"
- [build]
- jobs = 4
- "#);
- assert_that(foo.cargo_process("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn invalid_global_config() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
-
- [dependencies]
- foo = "0.1.0"
- "#)
- .file(".cargo/config", "4")
- .file("src/lib.rs", "");
-
- assert_that(foo.cargo_process("build").arg("-v"),
- execs().with_status(101).with_stderr("\
-[ERROR] Couldn't load Cargo configuration
-
-Caused by:
- could not parse TOML configuration in `[..]config`
-
-Caused by:
- could not parse input as TOML
-[..]config:1:2 expected `=`, but found eof
-
-"));
-}
-
-#[test]
-fn bad_cargo_lock() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- "#)
- .file("Cargo.lock", "")
- .file("src/lib.rs", "");
-
- assert_that(foo.cargo_process("build").arg("-v"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse lock file at: [..]Cargo.lock
-
-Caused by:
- expected a section for the key `root`
-"));
-}
-
-#[test]
-fn bad_git_dependency() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
-
- [dependencies]
- foo = { git = "file:.." }
- "#)
- .file("src/lib.rs", "");
-
- assert_that(foo.cargo_process("build").arg("-v"),
- execs().with_status(101).with_stderr("\
-[UPDATING] git repository `file:///`
-[ERROR] Unable to update file:///
-
-Caused by:
- failed to clone into: [..]
-
-Caused by:
- [[..]] 'file:///' is not a valid local file URI
-"));
-}
-
-#[test]
-fn bad_crate_type() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
-
- [lib]
- crate-type = ["bad_type", "rlib"]
- "#)
- .file("src/lib.rs", "");
-
- assert_that(foo.cargo_process("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-warning: crate-type \"bad_type\" was not one of lib|rlib|dylib|staticlib
-[COMPILING] foo v0.0.0 (file:///[..])
-[RUNNING] `rustc [..] --crate-type rlib [..]`
-"));
-}
-
-#[test]
-fn malformed_override() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
-
- [target.x86_64-apple-darwin.freetype]
- native = {
- foo: "bar"
- }
- "#)
- .file("src/lib.rs", "");
-
- assert_that(foo.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- could not parse input as TOML
-Cargo.toml:[..]
-
-"));
-}
-
-#[test]
-fn duplicate_binary_names() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "qqq"
- version = "0.1.0"
- authors = ["A <a@a.a>"]
-
- [[bin]]
- name = "e"
- path = "a.rs"
-
- [[bin]]
- name = "e"
- path = "b.rs"
- "#)
- .file("a.rs", r#"fn main() -> () {}"#)
- .file("b.rs", r#"fn main() -> () {}"#);
-
- assert_that(foo.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- found duplicate binary name e, but all binary targets must have a unique name
-"));
-}
-
-#[test]
-fn duplicate_example_names() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "qqq"
- version = "0.1.0"
- authors = ["A <a@a.a>"]
-
- [[example]]
- name = "ex"
- path = "examples/ex.rs"
-
- [[example]]
- name = "ex"
- path = "examples/ex2.rs"
- "#)
- .file("examples/ex.rs", r#"fn main () -> () {}"#)
- .file("examples/ex2.rs", r#"fn main () -> () {}"#);
-
- assert_that(foo.cargo_process("build").arg("--example").arg("ex"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- found duplicate example name ex, but all binary targets must have a unique name
-"));
-}
-
-#[test]
-fn duplicate_bench_names() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "qqq"
- version = "0.1.0"
- authors = ["A <a@a.a>"]
-
- [[bench]]
- name = "ex"
- path = "benches/ex.rs"
-
- [[bench]]
- name = "ex"
- path = "benches/ex2.rs"
- "#)
- .file("benches/ex.rs", r#"fn main () {}"#)
- .file("benches/ex2.rs", r#"fn main () {}"#);
-
- assert_that(foo.cargo_process("bench"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- found duplicate bench name ex, but all binary targets must have a unique name
-"));
-}
-
-#[test]
-fn duplicate_deps() {
- let foo = project("foo")
- .file("shim-bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("shim-bar/src/lib.rs", r#"
- pub fn a() {}
- "#)
- .file("linux-bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("linux-bar/src/lib.rs", r#"
- pub fn a() {}
- "#)
- .file("Cargo.toml", r#"
- [package]
- name = "qqq"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = { path = "shim-bar" }
-
- [target.x86_64-unknown-linux-gnu.dependencies]
- bar = { path = "linux-bar" }
- "#)
- .file("src/main.rs", r#"fn main () {}"#);
-
- assert_that(foo.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- found duplicate dependency name bar, but all dependencies must have a unique name
-"));
-}
-
-#[test]
-fn unused_keys() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
-
- [target.foo]
- bar = "3"
- "#)
- .file("src/lib.rs", "");
-
- assert_that(foo.cargo_process("build"),
- execs().with_status(0).with_stderr("\
-warning: unused manifest key: target.foo.bar
-[COMPILING] foo v0.1.0 (file:///[..])
-"));
-}
-
-#[test]
-fn empty_dependencies() {
- let p = project("empty_deps")
- .file("Cargo.toml", r#"
- [package]
- name = "empty_deps"
- version = "0.0.0"
- authors = []
-
- [dependencies]
- foo = {}
- "#)
- .file("src/main.rs", "fn main() {}");
-
- Package::new("foo", "0.0.1").publish();
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr_contains("\
-warning: dependency (foo) specified without providing a local path, Git repository, or version \
-to use. This will be considered an error in future versions
-"));
-}
+++ /dev/null
-use support::{project, execs, main_file, basic_bin_manifest};
-use hamcrest::{assert_that};
-
-fn assert_not_a_cargo_toml(command: &str, manifest_path_argument: &str) {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process(command)
- .arg("--manifest-path").arg(manifest_path_argument)
- .cwd(p.root().parent().unwrap()),
- execs().with_status(101)
- .with_stderr("[ERROR] the manifest-path must be a path \
- to a Cargo.toml file"));
-}
-
-
-fn assert_cargo_toml_doesnt_exist(command: &str, manifest_path_argument: &str) {
- let p = project("foo");
- let expected_path = manifest_path_argument
- .split("/").collect::<Vec<_>>().join("[..]");
-
- assert_that(p.cargo_process(command)
- .arg("--manifest-path").arg(manifest_path_argument)
- .cwd(p.root().parent().unwrap()),
- execs().with_status(101)
- .with_stderr(
- format!("[ERROR] manifest path `{}` does not exist",
- expected_path)
- ));
-}
-
-#[test]
-fn bench_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("bench", "foo");
-}
-
-#[test]
-fn bench_dir_plus_file() {
- assert_not_a_cargo_toml("bench", "foo/bar");
-}
-
-#[test]
-fn bench_dir_plus_path() {
- assert_not_a_cargo_toml("bench", "foo/bar/baz");
-}
-
-#[test]
-fn bench_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("bench", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn build_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("build", "foo");
-}
-
-#[test]
-fn build_dir_plus_file() {
- assert_not_a_cargo_toml("bench", "foo/bar");
-}
-
-#[test]
-fn build_dir_plus_path() {
- assert_not_a_cargo_toml("bench", "foo/bar/baz");
-}
-
-#[test]
-fn build_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("build", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn clean_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("clean", "foo");
-}
-
-#[test]
-fn clean_dir_plus_file() {
- assert_not_a_cargo_toml("clean", "foo/bar");
-}
-
-#[test]
-fn clean_dir_plus_path() {
- assert_not_a_cargo_toml("clean", "foo/bar/baz");
-}
-
-#[test]
-fn clean_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("clean", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn doc_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("doc", "foo");
-}
-
-#[test]
-fn doc_dir_plus_file() {
- assert_not_a_cargo_toml("doc", "foo/bar");
-}
-
-#[test]
-fn doc_dir_plus_path() {
- assert_not_a_cargo_toml("doc", "foo/bar/baz");
-}
-
-#[test]
-fn doc_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("doc", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn fetch_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("fetch", "foo");
-}
-
-#[test]
-fn fetch_dir_plus_file() {
- assert_not_a_cargo_toml("fetch", "foo/bar");
-}
-
-#[test]
-fn fetch_dir_plus_path() {
- assert_not_a_cargo_toml("fetch", "foo/bar/baz");
-}
-
-#[test]
-fn fetch_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("fetch", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn generate_lockfile_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("generate-lockfile", "foo");
-}
-
-#[test]
-fn generate_lockfile_dir_plus_file() {
- assert_not_a_cargo_toml("generate-lockfile", "foo/bar");
-}
-
-#[test]
-fn generate_lockfile_dir_plus_path() {
- assert_not_a_cargo_toml("generate-lockfile", "foo/bar/baz");
-}
-
-#[test]
-fn generate_lockfile_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("generate-lockfile", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn package_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("package", "foo");
-}
-
-#[test]
-fn package_dir_plus_file() {
- assert_not_a_cargo_toml("package", "foo/bar");
-}
-
-#[test]
-fn package_dir_plus_path() {
- assert_not_a_cargo_toml("package", "foo/bar/baz");
-}
-
-#[test]
-fn package_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("package", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn pkgid_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("pkgid", "foo");
-}
-
-#[test]
-fn pkgid_dir_plus_file() {
- assert_not_a_cargo_toml("pkgid", "foo/bar");
-}
-
-#[test]
-fn pkgid_dir_plus_path() {
- assert_not_a_cargo_toml("pkgid", "foo/bar/baz");
-}
-
-#[test]
-fn pkgid_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("pkgid", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn publish_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("publish", "foo");
-}
-
-#[test]
-fn publish_dir_plus_file() {
- assert_not_a_cargo_toml("publish", "foo/bar");
-}
-
-#[test]
-fn publish_dir_plus_path() {
- assert_not_a_cargo_toml("publish", "foo/bar/baz");
-}
-
-#[test]
-fn publish_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("publish", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn read_manifest_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("read-manifest", "foo");
-}
-
-#[test]
-fn read_manifest_dir_plus_file() {
- assert_not_a_cargo_toml("read-manifest", "foo/bar");
-}
-
-#[test]
-fn read_manifest_dir_plus_path() {
- assert_not_a_cargo_toml("read-manifest", "foo/bar/baz");
-}
-
-#[test]
-fn read_manifest_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("read-manifest", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn run_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("run", "foo");
-}
-
-#[test]
-fn run_dir_plus_file() {
- assert_not_a_cargo_toml("run", "foo/bar");
-}
-
-#[test]
-fn run_dir_plus_path() {
- assert_not_a_cargo_toml("run", "foo/bar/baz");
-}
-
-#[test]
-fn run_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("run", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn rustc_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("rustc", "foo");
-}
-
-#[test]
-fn rustc_dir_plus_file() {
- assert_not_a_cargo_toml("rustc", "foo/bar");
-}
-
-#[test]
-fn rustc_dir_plus_path() {
- assert_not_a_cargo_toml("rustc", "foo/bar/baz");
-}
-
-#[test]
-fn rustc_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("rustc", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn test_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("test", "foo");
-}
-
-#[test]
-fn test_dir_plus_file() {
- assert_not_a_cargo_toml("test", "foo/bar");
-}
-
-#[test]
-fn test_dir_plus_path() {
- assert_not_a_cargo_toml("test", "foo/bar/baz");
-}
-
-#[test]
-fn test_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("test", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn update_dir_containing_cargo_toml() {
- assert_not_a_cargo_toml("update", "foo");
-}
-
-#[test]
-fn update_dir_plus_file() {
- assert_not_a_cargo_toml("update", "foo/bar");
-}
-
-#[test]
-fn update_dir_plus_path() {
- assert_not_a_cargo_toml("update", "foo/bar/baz");
-}
-
-#[test]
-fn update_dir_to_nonexistent_cargo_toml() {
- assert_cargo_toml_doesnt_exist("update", "foo/bar/baz/Cargo.toml");
-}
-
-#[test]
-fn verify_project_dir_containing_cargo_toml() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("verify-project")
- .arg("--manifest-path").arg("foo")
- .cwd(p.root().parent().unwrap()),
- execs().with_status(1)
- .with_stdout("\
-{\"invalid\":\"the manifest-path must be a path to a Cargo.toml file\"}\
- "));
-}
-
-#[test]
-fn verify_project_dir_plus_file() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("verify-project")
- .arg("--manifest-path").arg("foo/bar")
- .cwd(p.root().parent().unwrap()),
- execs().with_status(1)
- .with_stdout("\
-{\"invalid\":\"the manifest-path must be a path to a Cargo.toml file\"}\
- "));
-}
-
-#[test]
-fn verify_project_dir_plus_path() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("verify-project")
- .arg("--manifest-path").arg("foo/bar/baz")
- .cwd(p.root().parent().unwrap()),
- execs().with_status(1)
- .with_stdout("\
-{\"invalid\":\"the manifest-path must be a path to a Cargo.toml file\"}\
- "));
-}
-
-#[test]
-fn verify_project_dir_to_nonexistent_cargo_toml() {
- let p = project("foo");
- assert_that(p.cargo_process("verify-project")
- .arg("--manifest-path").arg("foo/bar/baz/Cargo.toml")
- .cwd(p.root().parent().unwrap()),
- execs().with_status(1)
- .with_stdout("\
-{\"invalid\":\"manifest path `foo[..]bar[..]baz[..]Cargo.toml` does not exist\"}\
- "));
-}
+++ /dev/null
-use std::env;
-use std::ffi::OsString;
-use std::fs::{self, File};
-use std::io::prelude::*;
-use std::path::{Path, PathBuf};
-use std::str;
-
-use cargo_process;
-use support::paths;
-use support::{execs, project, mkdir_recursive, ProjectBuilder};
-use hamcrest::{assert_that};
-
-#[cfg_attr(windows,allow(dead_code))]
-enum FakeKind<'a> {
- Executable,
- Symlink{target:&'a Path},
-}
-
-/// Add an empty file with executable flags (and platform-dependent suffix).
-/// TODO: move this to `ProjectBuilder` if other cases using this emerge.
-fn fake_file(proj: ProjectBuilder, dir: &Path, name: &str, kind: FakeKind) -> ProjectBuilder {
- let path = proj.root().join(dir).join(&format!("{}{}", name,
- env::consts::EXE_SUFFIX));
- mkdir_recursive(path.parent().unwrap()).unwrap();
- match kind {
- FakeKind::Executable => {
- File::create(&path).unwrap();
- make_executable(&path);
- },
- FakeKind::Symlink{target} => {
- make_symlink(&path,target);
- }
- }
- return proj;
-
- #[cfg(unix)]
- fn make_executable(p: &Path) {
- use std::os::unix::prelude::*;
-
- let mut perms = fs::metadata(p).unwrap().permissions();
- let mode = perms.mode();
- perms.set_mode(mode | 0o111);
- fs::set_permissions(p, perms).unwrap();
- }
- #[cfg(windows)]
- fn make_executable(_: &Path) {}
- #[cfg(unix)]
- fn make_symlink(p: &Path, t: &Path) {
- ::std::os::unix::fs::symlink(t,p).expect("Failed to create symlink");
- }
- #[cfg(windows)]
- fn make_symlink(_: &Path, _: &Path) {
- panic!("Not supported")
- }
-}
-
-fn path() -> Vec<PathBuf> {
- env::split_paths(&env::var_os("PATH").unwrap_or(OsString::new())).collect()
-}
-
-#[test]
-fn list_command_looks_at_path() {
- let proj = project("list-non-overlapping");
- let proj = fake_file(proj, &Path::new("path-test"), "cargo-1", FakeKind::Executable);
- let mut pr = cargo_process();
-
- let mut path = path();
- path.push(proj.root().join("path-test"));
- let path = env::join_paths(path.iter()).unwrap();
- let output = pr.arg("-v").arg("--list")
- .env("PATH", &path);
- let output = output.exec_with_output().unwrap();
- let output = str::from_utf8(&output.stdout).unwrap();
- assert!(output.contains("\n 1\n"), "missing 1: {}", output);
-}
-
-// windows and symlinks don't currently agree that well
-#[cfg(unix)]
-#[test]
-fn list_command_resolves_symlinks() {
- use support::cargo_dir;
-
- let proj = project("list-non-overlapping");
- let proj = fake_file(proj, &Path::new("path-test"), "cargo-2",
- FakeKind::Symlink{target:&cargo_dir().join("cargo")});
- let mut pr = cargo_process();
-
- let mut path = path();
- path.push(proj.root().join("path-test"));
- let path = env::join_paths(path.iter()).unwrap();
- let output = pr.arg("-v").arg("--list")
- .env("PATH", &path);
- let output = output.exec_with_output().unwrap();
- let output = str::from_utf8(&output.stdout).unwrap();
- assert!(output.contains("\n 2\n"), "missing 2: {}", output);
-}
-
-#[test]
-fn find_closest_biuld_to_build() {
- let mut pr = cargo_process();
- pr.arg("biuld");
-
- assert_that(pr,
- execs().with_status(101)
- .with_stderr("[ERROR] no such subcommand
-
-<tab>Did you mean `build`?
-
-"));
-}
-
-// if a subcommand is more than 3 edit distance away, we don't make a suggestion
-#[test]
-fn find_closest_dont_correct_nonsense() {
- let mut pr = cargo_process();
- pr.arg("there-is-no-way-that-there-is-a-command-close-to-this")
- .cwd(&paths::root());
-
- assert_that(pr,
- execs().with_status(101)
- .with_stderr("[ERROR] no such subcommand
-"));
-}
-
-#[test]
-fn override_cargo_home() {
- let root = paths::root();
- let my_home = root.join("my_home");
- fs::create_dir(&my_home).unwrap();
- File::create(&my_home.join("config")).unwrap().write_all(br#"
- [cargo-new]
- name = "foo"
- email = "bar"
- git = false
- "#).unwrap();
-
- assert_that(cargo_process()
- .arg("new").arg("foo")
- .env("USER", "foo")
- .env("CARGO_HOME", &my_home),
- execs().with_status(0));
-
- let toml = paths::root().join("foo/Cargo.toml");
- let mut contents = String::new();
- File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"authors = ["foo <bar>"]"#));
-}
-
-#[test]
-fn cargo_help() {
- assert_that(cargo_process(),
- execs().with_status(0));
- assert_that(cargo_process().arg("help"),
- execs().with_status(0));
- assert_that(cargo_process().arg("-h"),
- execs().with_status(0));
- assert_that(cargo_process().arg("help").arg("build"),
- execs().with_status(0));
- assert_that(cargo_process().arg("build").arg("-h"),
- execs().with_status(0));
- assert_that(cargo_process().arg("help").arg("-h"),
- execs().with_status(0));
- assert_that(cargo_process().arg("help").arg("help"),
- execs().with_status(0));
-}
-
-#[test]
-fn explain() {
- assert_that(cargo_process().arg("--explain").arg("E0001"),
- execs().with_status(0));
-}
+++ /dev/null
-use std::str;
-
-use support::{project, execs, basic_bin_manifest, basic_lib_manifest};
-use support::paths::CargoPathExt;
-use hamcrest::{assert_that, existing_file};
-use cargo::util::process;
-
-#[test]
-fn cargo_bench_simple() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", r#"
- #![feature(test)]
- extern crate test;
-
- fn hello() -> &'static str {
- "hello"
- }
-
- pub fn main() {
- println!("{}", hello())
- }
-
- #[bench]
- fn bench_hello(_b: &mut test::Bencher) {
- assert_eq!(hello(), "hello")
- }"#);
-
- assert_that(p.cargo_process("build"), execs());
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("hello\n"));
-
- assert_that(p.cargo("bench"),
- execs().with_stderr(&format!("\
-[COMPILING] foo v0.5.0 ({})
-[RUNNING] target[..]release[..]foo-[..]", p.url()))
- .with_stdout("
-running 1 test
-test bench_hello ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"));
-}
-
-#[test]
-fn bench_tarname() {
- if !::is_nightly() { return }
-
- let prj = project("foo")
- .file("Cargo.toml" , r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("benches/bin1.rs", r#"
- #![feature(test)]
- extern crate test;
- #[bench] fn run1(_ben: &mut test::Bencher) { }"#)
- .file("benches/bin2.rs", r#"
- #![feature(test)]
- extern crate test;
- #[bench] fn run2(_ben: &mut test::Bencher) { }"#);
-
- assert_that(prj.cargo_process("bench").arg("--bench").arg("bin2"),
- execs().with_status(0)
- .with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] target[..]release[..]bin2[..]
-", dir = prj.url()))
- .with_stdout("
-running 1 test
-test run2 ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"));
-}
-
-#[test]
-fn cargo_bench_verbose() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", r#"
- #![feature(test)]
- extern crate test;
- fn main() {}
- #[bench] fn bench_hello(_b: &mut test::Bencher) {}
- "#);
-
- assert_that(p.cargo_process("bench").arg("-v").arg("hello"),
- execs().with_stderr(&format!("\
-[COMPILING] foo v0.5.0 ({url})
-[RUNNING] `rustc src[..]foo.rs [..]`
-[RUNNING] `[..]target[..]release[..]foo-[..] hello --bench`", url = p.url()))
- .with_stdout("
-running 1 test
-test bench_hello ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"));
-}
-
-#[test]
-fn many_similar_names() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "
- #![feature(test)]
- extern crate test;
- pub fn foo() {}
- #[bench] fn lib_bench(_b: &mut test::Bencher) {}
- ")
- .file("src/main.rs", "
- #![feature(test)]
- extern crate foo;
- extern crate test;
- fn main() {}
- #[bench] fn bin_bench(_b: &mut test::Bencher) { foo::foo() }
- ")
- .file("benches/foo.rs", r#"
- #![feature(test)]
- extern crate foo;
- extern crate test;
- #[bench] fn bench_bench(_b: &mut test::Bencher) { foo::foo() }
- "#);
-
- let output = p.cargo_process("bench").exec_with_output().unwrap();
- let output = str::from_utf8(&output.stdout).unwrap();
- assert!(output.contains("test bin_bench"), "bin_bench missing\n{}", output);
- assert!(output.contains("test lib_bench"), "lib_bench missing\n{}", output);
- assert!(output.contains("test bench_bench"), "bench_bench missing\n{}", output);
-}
-
-#[test]
-fn cargo_bench_failing_test() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", r#"
- #![feature(test)]
- extern crate test;
- fn hello() -> &'static str {
- "hello"
- }
-
- pub fn main() {
- println!("{}", hello())
- }
-
- #[bench]
- fn bench_hello(_b: &mut test::Bencher) {
- assert_eq!(hello(), "nope")
- }"#);
-
- assert_that(p.cargo_process("build"), execs());
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("hello\n"));
-
- assert_that(p.cargo("bench"),
- execs().with_stdout_contains("
-running 1 test
-test bench_hello ... ")
- .with_stderr_contains(format!("\
-[COMPILING] foo v0.5.0 ({})
-[RUNNING] target[..]release[..]foo-[..]
-thread '<main>' panicked at 'assertion failed: \
- `(left == right)` (left: \
- `\"hello\"`, right: `\"nope\"`)', src[..]foo.rs:14
-[..]
-", p.url()))
- .with_status(101));
-}
-
-#[test]
-fn bench_with_lib_dep() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [[bin]]
- name = "baz"
- path = "src/main.rs"
- "#)
- .file("src/lib.rs", r#"
- #![feature(test)]
- extern crate test;
- ///
- /// ```rust
- /// extern crate foo;
- /// fn main() {
- /// println!("{}", foo::foo());
- /// }
- /// ```
- ///
- pub fn foo(){}
- #[bench] fn lib_bench(_b: &mut test::Bencher) {}
- "#)
- .file("src/main.rs", "
- #![feature(test)]
- extern crate foo;
- extern crate test;
-
- fn main() {}
-
- #[bench]
- fn bin_bench(_b: &mut test::Bencher) {}
- ");
-
- assert_that(p.cargo_process("bench"),
- execs().with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({})
-[RUNNING] target[..]release[..]baz-[..]
-[RUNNING] target[..]release[..]foo-[..]", p.url()))
- .with_stdout("
-running 1 test
-test bin_bench ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-
-running 1 test
-test lib_bench ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"))
-}
-
-#[test]
-fn bench_with_deep_lib_dep() {
- if !::is_nightly() { return }
-
- let p = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [dependencies.foo]
- path = "../foo"
- "#)
- .file("src/lib.rs", "
- #![feature(test)]
- extern crate foo;
- extern crate test;
- #[bench]
- fn bar_bench(_b: &mut test::Bencher) {
- foo::foo();
- }
- ");
- let p2 = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "
- #![feature(test)]
- extern crate test;
-
- pub fn foo() {}
-
- #[bench]
- fn foo_bench(_b: &mut test::Bencher) {}
- ");
-
- p2.build();
- assert_that(p.cargo_process("bench"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ([..])
-[COMPILING] bar v0.0.1 ({dir})
-[RUNNING] target[..]", dir = p.url()))
- .with_stdout("
-running 1 test
-test bar_bench ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"));
-}
-
-#[test]
-fn external_bench_explicit() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [[bench]]
- name = "bench"
- path = "src/bench.rs"
- "#)
- .file("src/lib.rs", r#"
- #![feature(test)]
- extern crate test;
- pub fn get_hello() -> &'static str { "Hello" }
-
- #[bench]
- fn internal_bench(_b: &mut test::Bencher) {}
- "#)
- .file("src/bench.rs", r#"
- #![feature(test)]
- extern crate foo;
- extern crate test;
-
- #[bench]
- fn external_bench(_b: &mut test::Bencher) {}
- "#);
-
- assert_that(p.cargo_process("bench"),
- execs().with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({})
-[RUNNING] target[..]release[..]bench-[..]
-[RUNNING] target[..]release[..]foo-[..]", p.url()))
- .with_stdout("
-running 1 test
-test external_bench ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-
-running 1 test
-test internal_bench ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"))
-}
-
-#[test]
-fn external_bench_implicit() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- #![feature(test)]
- extern crate test;
-
- pub fn get_hello() -> &'static str { "Hello" }
-
- #[bench]
- fn internal_bench(_b: &mut test::Bencher) {}
- "#)
- .file("benches/external.rs", r#"
- #![feature(test)]
- extern crate foo;
- extern crate test;
-
- #[bench]
- fn external_bench(_b: &mut test::Bencher) {}
- "#);
-
- assert_that(p.cargo_process("bench"),
- execs().with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({})
-[RUNNING] target[..]release[..]external-[..]
-[RUNNING] target[..]release[..]foo-[..]", p.url()))
- .with_stdout("
-running 1 test
-test external_bench ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-
-running 1 test
-test internal_bench ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"))
-}
-
-#[test]
-fn dont_run_examples() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- "#)
- .file("examples/dont-run-me-i-will-fail.rs", r#"
- fn main() { panic!("Examples should not be run by 'cargo test'"); }
- "#);
- assert_that(p.cargo_process("bench"),
- execs().with_status(0));
-}
-
-#[test]
-fn pass_through_command_line() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "
- #![feature(test)]
- extern crate test;
-
- #[bench] fn foo(_b: &mut test::Bencher) {}
- #[bench] fn bar(_b: &mut test::Bencher) {}
- ");
-
- assert_that(p.cargo_process("bench").arg("bar"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] target[..]release[..]foo-[..]", dir = p.url()))
- .with_stdout("
-running 1 test
-test bar ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"));
-
- assert_that(p.cargo("bench").arg("foo"),
- execs().with_status(0)
- .with_stderr("\
-[RUNNING] target[..]release[..]foo-[..]")
- .with_stdout("
-running 1 test
-test foo ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"));
-}
-
-// Regression test for running cargo-bench twice with
-// tests in an rlib
-#[test]
-fn cargo_bench_twice() {
- if !::is_nightly() { return }
-
- let p = project("test_twice")
- .file("Cargo.toml", &basic_lib_manifest("test_twice"))
- .file("src/test_twice.rs", r#"
- #![crate_type = "rlib"]
- #![feature(test)]
-
- extern crate test;
-
- #[bench]
- fn dummy_bench(b: &mut test::Bencher) { }
- "#);
-
- p.cargo_process("build");
-
- for _ in 0..2 {
- assert_that(p.cargo("bench"),
- execs().with_status(0));
- }
-}
-
-#[test]
-fn lib_bin_same_name() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo"
- [[bin]]
- name = "foo"
- "#)
- .file("src/lib.rs", "
- #![feature(test)]
- extern crate test;
- #[bench] fn lib_bench(_b: &mut test::Bencher) {}
- ")
- .file("src/main.rs", "
- #![feature(test)]
- extern crate foo;
- extern crate test;
-
- #[bench]
- fn bin_bench(_b: &mut test::Bencher) {}
- ");
-
- assert_that(p.cargo_process("bench"),
- execs().with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({})
-[RUNNING] target[..]release[..]foo-[..]
-[RUNNING] target[..]release[..]foo-[..]", p.url()))
- .with_stdout("
-running 1 test
-test [..] ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-
-running 1 test
-test [..] ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"))
-}
-
-#[test]
-fn lib_with_standard_name() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "syntax"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "
- #![feature(test)]
- extern crate test;
-
- /// ```
- /// syntax::foo();
- /// ```
- pub fn foo() {}
-
- #[bench]
- fn foo_bench(_b: &mut test::Bencher) {}
- ")
- .file("benches/bench.rs", "
- #![feature(test)]
- extern crate syntax;
- extern crate test;
-
- #[bench]
- fn bench(_b: &mut test::Bencher) { syntax::foo() }
- ");
-
- assert_that(p.cargo_process("bench"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] syntax v0.0.1 ({dir})
-[RUNNING] target[..]release[..]bench-[..]
-[RUNNING] target[..]release[..]syntax-[..]", dir = p.url()))
- .with_stdout("
-running 1 test
-test bench ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-
-running 1 test
-test foo_bench ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"));
-}
-
-#[test]
-fn lib_with_standard_name2() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "syntax"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "syntax"
- bench = false
- doctest = false
- "#)
- .file("src/lib.rs", "
- pub fn foo() {}
- ")
- .file("src/main.rs", "
- #![feature(test)]
- extern crate syntax;
- extern crate test;
-
- fn main() {}
-
- #[bench]
- fn bench(_b: &mut test::Bencher) { syntax::foo() }
- ");
-
- assert_that(p.cargo_process("bench"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] syntax v0.0.1 ({dir})
-[RUNNING] target[..]release[..]syntax-[..]", dir = p.url()))
- .with_stdout("
-running 1 test
-test bench ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"));
-}
-
-#[test]
-fn bench_dylib() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo"
- crate_type = ["dylib"]
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/lib.rs", r#"
- #![feature(test)]
- extern crate bar as the_bar;
- extern crate test;
-
- pub fn bar() { the_bar::baz(); }
-
- #[bench]
- fn foo(_b: &mut test::Bencher) {}
- "#)
- .file("benches/bench.rs", r#"
- #![feature(test)]
- extern crate foo as the_foo;
- extern crate test;
-
- #[bench]
- fn foo(_b: &mut test::Bencher) { the_foo::bar(); }
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "bar"
- crate_type = ["dylib"]
- "#)
- .file("bar/src/lib.rs", "
- pub fn baz() {}
- ");
-
- assert_that(p.cargo_process("bench").arg("-v"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] bar v0.0.1 ({dir}/bar)
-[RUNNING] [..] -C opt-level=3 [..]
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] [..] -C opt-level=3 [..]
-[RUNNING] [..] -C opt-level=3 [..]
-[RUNNING] [..] -C opt-level=3 [..]
-[RUNNING] [..]target[..]release[..]bench-[..]
-[RUNNING] [..]target[..]release[..]foo-[..]", dir = p.url()))
- .with_stdout("
-running 1 test
-test foo ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-
-running 1 test
-test foo ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"));
- p.root().move_into_the_past().unwrap();
- assert_that(p.cargo("bench").arg("-v"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[FRESH] bar v0.0.1 ({dir}/bar)
-[FRESH] foo v0.0.1 ({dir})
-[RUNNING] [..]target[..]release[..]bench-[..]
-[RUNNING] [..]target[..]release[..]foo-[..]", dir = p.url()))
- .with_stdout("
-running 1 test
-test foo ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-
-running 1 test
-test foo ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"));
-}
-
-#[test]
-fn bench_twice_with_build_cmd() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- "#)
- .file("build.rs", "fn main() {}")
- .file("src/lib.rs", "
- #![feature(test)]
- extern crate test;
- #[bench]
- fn foo(_b: &mut test::Bencher) {}
- ");
-
- assert_that(p.cargo_process("bench"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] target[..]release[..]foo-[..]", dir = p.url()))
- .with_stdout("
-running 1 test
-test foo ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"));
-
- assert_that(p.cargo("bench"),
- execs().with_status(0)
- .with_stderr("\
-[RUNNING] target[..]release[..]foo-[..]")
- .with_stdout("
-running 1 test
-test foo ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"));
-}
-
-#[test]
-fn bench_with_examples() {
- if !::is_nightly() { return }
-
- let p = project("testbench")
- .file("Cargo.toml", r#"
- [package]
- name = "testbench"
- version = "6.6.6"
- authors = []
-
- [[example]]
- name = "teste1"
-
- [[bench]]
- name = "testb1"
- "#)
- .file("src/lib.rs", r#"
- #![feature(test)]
- extern crate test;
- #[cfg(test)]
- use test::Bencher;
-
- pub fn f1() {
- println!("f1");
- }
-
- pub fn f2() {}
-
- #[bench]
- fn bench_bench1(_b: &mut Bencher) {
- f2();
- }
- "#)
- .file("benches/testb1.rs", "
- #![feature(test)]
- extern crate testbench;
- extern crate test;
-
- use test::Bencher;
-
- #[bench]
- fn bench_bench2(_b: &mut Bencher) {
- testbench::f2();
- }
- ")
- .file("examples/teste1.rs", r#"
- extern crate testbench;
-
- fn main() {
- println!("example1");
- testbench::f1();
- }
- "#);
-
- assert_that(p.cargo_process("bench").arg("-v"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] testbench v6.6.6 ({url})
-[RUNNING] `rustc [..]`
-[RUNNING] `rustc [..]`
-[RUNNING] `rustc [..]`
-[RUNNING] `{dir}[..]target[..]release[..]testb1-[..] --bench`
-[RUNNING] `{dir}[..]target[..]release[..]testbench-[..] --bench`",
- dir = p.root().display(), url = p.url()))
- .with_stdout("
-running 1 test
-test bench_bench2 ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-
-running 1 test
-test bench_bench1 ... bench: [..] 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-
-"));
-}
-
-#[test]
-fn test_a_bench() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- authors = []
- version = "0.1.0"
-
- [lib]
- name = "foo"
- test = false
- doctest = false
-
- [[bench]]
- name = "b"
- test = true
- "#)
- .file("src/lib.rs", "")
- .file("benches/b.rs", r#"
- #[test]
- fn foo() {}
- "#);
-
- assert_that(p.cargo_process("test"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] foo v0.1.0 ([..])
-[RUNNING] target[..]debug[..]b-[..]")
- .with_stdout("
-running 1 test
-test foo ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn test_bench_no_run() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- authors = []
- version = "0.1.0"
- "#)
- .file("src/lib.rs", "")
- .file("benches/bbaz.rs", r#"
- #![feature(test)]
-
- extern crate test;
-
- use test::Bencher;
-
- #[bench]
- fn bench_baz(_: &mut Bencher) {}
- "#);
-
- assert_that(p.cargo_process("bench").arg("--no-run"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] foo v0.1.0 ([..])
-"));
-}
-
-#[test]
-fn test_bench_multiple_packages() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- authors = []
- version = "0.1.0"
-
- [dependencies.bar]
- path = "../bar"
-
- [dependencies.baz]
- path = "../baz"
- "#)
- .file("src/lib.rs", "");
-
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [project]
- name = "bar"
- authors = []
- version = "0.1.0"
-
- [[bench]]
- name = "bbar"
- test = true
- "#)
- .file("src/lib.rs", "")
- .file("benches/bbar.rs", r#"
- #![feature(test)]
- extern crate test;
-
- use test::Bencher;
-
- #[bench]
- fn bench_bar(_b: &mut Bencher) {}
- "#);
- bar.build();
-
- let baz = project("baz")
- .file("Cargo.toml", r#"
- [project]
- name = "baz"
- authors = []
- version = "0.1.0"
-
- [[bench]]
- name = "bbaz"
- test = true
- "#)
- .file("src/lib.rs", "")
- .file("benches/bbaz.rs", r#"
- #![feature(test)]
- extern crate test;
-
- use test::Bencher;
-
- #[bench]
- fn bench_baz(_b: &mut Bencher) {}
- "#);
- baz.build();
-
-
- assert_that(p.cargo_process("bench").arg("-p").arg("bar").arg("-p").arg("baz"),
- execs().with_status(0)
- .with_stderr_contains("\
-[RUNNING] target[..]release[..]bbaz-[..]")
- .with_stdout_contains("
-running 1 test
-test bench_baz ... bench: 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-")
- .with_stderr_contains("\
-[RUNNING] target[..]release[..]bbar-[..]")
- .with_stdout_contains("
-running 1 test
-test bench_bar ... bench: 0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-"));
-}
+++ /dev/null
-use std::collections::HashSet;
-use std::io::prelude::*;
-use std::net::TcpListener;
-use std::thread;
-
-use bufstream::BufStream;
-use git2;
-
-use support::{project, execs};
-use support::paths;
-use hamcrest::assert_that;
-
-// Test that HTTP auth is offered from `credential.helper`
-#[test]
-fn http_auth_offered() {
- let a = TcpListener::bind("127.0.0.1:0").unwrap();
- let addr = a.local_addr().unwrap();
-
- fn headers(rdr: &mut BufRead) -> HashSet<String> {
- let valid = ["GET", "Authorization", "Accept", "User-Agent"];
- rdr.lines().map(|s| s.unwrap())
- .take_while(|s| s.len() > 2)
- .map(|s| s.trim().to_string())
- .filter(|s| {
- valid.iter().any(|prefix| s.starts_with(*prefix))
- })
- .collect()
- }
-
- let t = thread::spawn(move|| {
- let mut s = BufStream::new(a.accept().unwrap().0);
- let req = headers(&mut s);
- s.write_all(b"\
- HTTP/1.1 401 Unauthorized\r\n\
- WWW-Authenticate: Basic realm=\"wheee\"\r\n
- \r\n\
- ").unwrap();
- assert_eq!(req, vec![
- "GET /foo/bar/info/refs?service=git-upload-pack HTTP/1.1",
- "Accept: */*",
- "User-Agent: git/1.0 (libgit2 0.23.0)",
- ].into_iter().map(|s| s.to_string()).collect());
- drop(s);
-
- let mut s = BufStream::new(a.accept().unwrap().0);
- let req = headers(&mut s);
- s.write_all(b"\
- HTTP/1.1 401 Unauthorized\r\n\
- WWW-Authenticate: Basic realm=\"wheee\"\r\n
- \r\n\
- ").unwrap();
- assert_eq!(req, vec![
- "GET /foo/bar/info/refs?service=git-upload-pack HTTP/1.1",
- "Authorization: Basic Zm9vOmJhcg==",
- "Accept: */*",
- "User-Agent: git/1.0 (libgit2 0.23.0)",
- ].into_iter().map(|s| s.to_string()).collect());
- });
-
- let script = project("script")
- .file("Cargo.toml", r#"
- [project]
- name = "script"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {
- println!("username=foo");
- println!("password=bar");
- }
- "#);
-
- assert_that(script.cargo_process("build").arg("-v"),
- execs().with_status(0));
- let script = script.bin("script");
-
- let config = paths::home().join(".gitconfig");
- let mut config = git2::Config::open(&config).unwrap();
- config.set_str("credential.helper",
- &script.display().to_string()).unwrap();
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- git = "http://127.0.0.1:{}/foo/bar"
- "#, addr.port()))
- .file("src/main.rs", "")
- .file(".cargo/config","\
- [net]
- retry = 0
- ");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr(&format!("\
-[UPDATING] git repository `http://{addr}/foo/bar`
-[ERROR] Unable to update http://{addr}/foo/bar
-
-Caused by:
- failed to clone into: [..]
-
-Caused by:
- failed to authenticate when downloading repository
-attempted to find username/password via `credential.helper`, but [..]
-
-To learn more, run the command again with --verbose.
-",
- addr = addr)));
-
- t.join().ok().unwrap();
-}
-
-// Boy, sure would be nice to have a TLS implementation in rust!
-#[test]
-fn https_something_happens() {
- let a = TcpListener::bind("127.0.0.1:0").unwrap();
- let addr = a.local_addr().unwrap();
- let t = thread::spawn(move|| {
- drop(a.accept().unwrap());
- });
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- git = "https://127.0.0.1:{}/foo/bar"
- "#, addr.port()))
- .file("src/main.rs", "")
- .file(".cargo/config","\
- [net]
- retry = 0
- ");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(101).with_stderr_contains(&format!("\
-[UPDATING] git repository `https://{addr}/foo/bar`
-",
- addr = addr,
- ))
- .with_stderr_contains(&format!("\
-Caused by:
- {errmsg}
-",
- errmsg = if cfg!(windows) {
- "[[..]] failed to send request: [..]\n"
- } else if cfg!(target_os = "macos") {
- // OSX is difficult to tests as some builds may use
- // Security.framework and others may use OpenSSL. In that case let's
- // just not verify the error message here.
- "[..]"
- } else {
- "[[..]] SSL error: [..]"
- })));
-
- t.join().ok().unwrap();
-}
-
-// Boy, sure would be nice to have an SSH implementation in rust!
-#[test]
-fn ssh_something_happens() {
- let a = TcpListener::bind("127.0.0.1:0").unwrap();
- let addr = a.local_addr().unwrap();
- let t = thread::spawn(move|| {
- drop(a.accept().unwrap());
- });
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- git = "ssh://127.0.0.1:{}/foo/bar"
- "#, addr.port()))
- .file("src/main.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(101).with_stderr_contains(&format!("\
-[UPDATING] git repository `ssh://{addr}/foo/bar`
-",
- addr = addr,
- ))
- .with_stderr_contains("\
-Caused by:
- [[..]] Failed to start SSH session: Failed getting banner
-"));
- t.join().ok().unwrap();
-}
+++ /dev/null
-use std::path::MAIN_SEPARATOR as SEP;
-use support::{basic_bin_manifest, execs, project, ProjectBuilder};
-use hamcrest::{assert_that};
-
-fn verbose_output_for_lib(p: &ProjectBuilder) -> String {
- format!("\
-[COMPILING] {name} v{version} ({url})
-[RUNNING] `rustc src{sep}lib.rs --crate-name {name} --crate-type lib -g \
- --out-dir {dir}{sep}target{sep}debug \
- --emit=dep-info,link \
- -L dependency={dir}{sep}target{sep}debug \
- -L dependency={dir}{sep}target{sep}debug{sep}deps`
-", sep = SEP,
- dir = p.root().display(), url = p.url(),
- name = "foo", version = "0.0.1")
-}
-
-#[test]
-fn build_lib_only() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
-
- name = "foo"
- version = "0.0.1"
- authors = ["wycats@example.com"]
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("src/lib.rs", r#" "#);
-
- assert_that(p.cargo_process("build").arg("--lib").arg("-v"),
- execs()
- .with_status(0)
- .with_stderr(verbose_output_for_lib(&p)));
-}
-
-
-#[test]
-fn build_with_no_lib() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/main.rs", r#"
- fn main() {}
- "#);
-
- assert_that(p.cargo_process("build").arg("--lib"),
- execs().with_status(101)
- .with_stderr("[ERROR] no library targets found"));
-}
-
-#[test]
-fn build_with_relative_cargo_home_path() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
-
- name = "foo"
- version = "0.0.1"
- authors = ["wycats@example.com"]
-
- [dependencies]
-
- "test-dependency" = { path = "src/test_dependency" }
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("src/test_dependency/src/lib.rs", r#" "#)
- .file("src/test_dependency/Cargo.toml", r#"
- [package]
-
- name = "test-dependency"
- version = "0.0.1"
- authors = ["wycats@example.com"]
- "#);
-
- assert_that(p.cargo_process("build").env("CARGO_HOME", "./cargo_home/"),
- execs()
- .with_status(0));
-}
+++ /dev/null
-use std::str::FromStr;
-use std::fmt;
-
-use cargo::util::{Cfg, CfgExpr};
-use hamcrest::assert_that;
-
-use support::{project, execs};
-use support::registry::Package;
-
-macro_rules! c {
- ($a:ident) => (
- Cfg::Name(stringify!($a).to_string())
- );
- ($a:ident = $e:expr) => (
- Cfg::KeyPair(stringify!($a).to_string(), $e.to_string())
- );
-}
-
-macro_rules! e {
- (any($($t:tt),*)) => (CfgExpr::Any(vec![$(e!($t)),*]));
- (all($($t:tt),*)) => (CfgExpr::All(vec![$(e!($t)),*]));
- (not($($t:tt)*)) => (CfgExpr::Not(Box::new(e!($($t)*))));
- (($($t:tt)*)) => (e!($($t)*));
- ($($t:tt)*) => (CfgExpr::Value(c!($($t)*)));
-}
-
-fn good<T>(s: &str, expected: T)
- where T: FromStr + PartialEq + fmt::Debug,
- T::Err: fmt::Display
-{
- let c = match T::from_str(s) {
- Ok(c) => c,
- Err(e) => panic!("failed to parse `{}`: {}", s, e),
- };
- assert_eq!(c, expected);
-}
-
-fn bad<T>(s: &str, err: &str)
- where T: FromStr + fmt::Display, T::Err: fmt::Display
-{
- let e = match T::from_str(s) {
- Ok(cfg) => panic!("expected `{}` to not parse but got {}", s, cfg),
- Err(e) => e.to_string(),
- };
- assert!(e.contains(err), "when parsing `{}`,\n\"{}\" not contained \
- inside: {}", s, err, e);
-}
-
-#[test]
-fn cfg_syntax() {
- good("foo", c!(foo));
- good("_bar", c!(_bar));
- good(" foo", c!(foo));
- good(" foo ", c!(foo));
- good(" foo = \"bar\"", c!(foo = "bar"));
- good("foo=\"\"", c!(foo = ""));
- good(" foo=\"3\" ", c!(foo = "3"));
- good("foo = \"3 e\"", c!(foo = "3 e"));
-}
-
-#[test]
-fn cfg_syntax_bad() {
- bad::<Cfg>("", "found nothing");
- bad::<Cfg>(" ", "found nothing");
- bad::<Cfg>("\t", "unexpected character");
- bad::<Cfg>("7", "unexpected character");
- bad::<Cfg>("=", "expected identifier");
- bad::<Cfg>(",", "expected identifier");
- bad::<Cfg>("(", "expected identifier");
- bad::<Cfg>("foo (", "malformed cfg value");
- bad::<Cfg>("bar =", "expected a string");
- bad::<Cfg>("bar = \"", "unterminated string");
- bad::<Cfg>("foo, bar", "malformed cfg value");
-}
-
-#[test]
-fn cfg_expr() {
- good("foo", e!(foo));
- good("_bar", e!(_bar));
- good(" foo", e!(foo));
- good(" foo ", e!(foo));
- good(" foo = \"bar\"", e!(foo = "bar"));
- good("foo=\"\"", e!(foo = ""));
- good(" foo=\"3\" ", e!(foo = "3"));
- good("foo = \"3 e\"", e!(foo = "3 e"));
-
- good("all()", e!(all()));
- good("all(a)", e!(all(a)));
- good("all(a, b)", e!(all(a, b)));
- good("all(a, )", e!(all(a)));
- good("not(a = \"b\")", e!(not(a = "b")));
- good("not(all(a))", e!(not(all(a))));
-}
-
-#[test]
-fn cfg_expr_bad() {
- bad::<CfgExpr>(" ", "found nothing");
- bad::<CfgExpr>(" all", "expected `(`");
- bad::<CfgExpr>("all(a", "expected `)`");
- bad::<CfgExpr>("not", "expected `(`");
- bad::<CfgExpr>("not(a", "expected `)`");
- bad::<CfgExpr>("a = ", "expected a string");
- bad::<CfgExpr>("all(not())", "expected identifier");
- bad::<CfgExpr>("foo(a)", "consider using all() or any() explicitly");
-}
-
-#[test]
-fn cfg_matches() {
- assert!(e!(foo).matches(&[c!(bar), c!(foo), c!(baz)]));
- assert!(e!(any(foo)).matches(&[c!(bar), c!(foo), c!(baz)]));
- assert!(e!(any(foo, bar)).matches(&[c!(bar)]));
- assert!(e!(any(foo, bar)).matches(&[c!(foo)]));
- assert!(e!(all(foo, bar)).matches(&[c!(foo), c!(bar)]));
- assert!(e!(all(foo, bar)).matches(&[c!(foo), c!(bar)]));
- assert!(e!(not(foo)).matches(&[c!(bar)]));
- assert!(e!(not(foo)).matches(&[]));
- assert!(e!(any((not(foo)), (all(foo, bar)))).matches(&[c!(bar)]));
- assert!(e!(any((not(foo)), (all(foo, bar)))).matches(&[c!(foo), c!(bar)]));
-
- assert!(!e!(foo).matches(&[]));
- assert!(!e!(foo).matches(&[c!(bar)]));
- assert!(!e!(foo).matches(&[c!(fo)]));
- assert!(!e!(any(foo)).matches(&[]));
- assert!(!e!(any(foo)).matches(&[c!(bar)]));
- assert!(!e!(any(foo)).matches(&[c!(bar), c!(baz)]));
- assert!(!e!(all(foo)).matches(&[c!(bar), c!(baz)]));
- assert!(!e!(all(foo, bar)).matches(&[c!(bar)]));
- assert!(!e!(all(foo, bar)).matches(&[c!(foo)]));
- assert!(!e!(all(foo, bar)).matches(&[]));
- assert!(!e!(not(bar)).matches(&[c!(bar)]));
- assert!(!e!(not(bar)).matches(&[c!(baz), c!(bar)]));
- assert!(!e!(any((not(foo)), (all(foo, bar)))).matches(&[c!(foo)]));
-}
-
-#[test]
-fn cfg_easy() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [target.'cfg(unix)'.dependencies]
- b = { path = 'b' }
- [target."cfg(windows)".dependencies]
- b = { path = 'b' }
- "#)
- .file("src/lib.rs", "extern crate b;")
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.0.1"
- authors = []
- "#)
- .file("b/src/lib.rs", "");
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn dont_include() {
- if !::is_nightly() { return }
-
- let other_family = if cfg!(unix) {"windows"} else {"unix"};
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [target.'cfg({})'.dependencies]
- b = {{ path = 'b' }}
- "#, other_family))
- .file("src/lib.rs", "")
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.0.1"
- authors = []
- "#)
- .file("b/src/lib.rs", "");
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr("\
-[COMPILING] a v0.0.1 ([..])
-"));
-}
-
-#[test]
-fn works_through_the_registry() {
- if !::is_nightly() { return }
-
- Package::new("foo", "0.1.0").publish();
- Package::new("bar", "0.1.0")
- .target_dep("foo", "0.1.0", "'cfg(unix)'")
- .target_dep("foo", "0.1.0", "'cfg(windows)'")
- .publish();
-
- let p = project("a")
- .file("Cargo.toml", &r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "0.1.0"
- "#)
- .file("src/lib.rs", "extern crate bar;");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry [..]
-[DOWNLOADING] [..]
-[DOWNLOADING] [..]
-[COMPILING] foo v0.1.0 ([..])
-[COMPILING] bar v0.1.0 ([..])
-[COMPILING] a v0.0.1 ([..])
-"));
-}
-
-#[test]
-fn bad_target_spec() {
- let p = project("a")
- .file("Cargo.toml", &r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [target.'cfg(4)'.dependencies]
- bar = "0.1.0"
- "#)
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- failed to parse `4` as a cfg expression
-
-Caused by:
- unexpected character in cfg `4`, [..]
-"));
-}
-
-#[test]
-fn bad_target_spec2() {
- let p = project("a")
- .file("Cargo.toml", &r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [target.'cfg(foo =)'.dependencies]
- bar = "0.1.0"
- "#)
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- failed to parse `foo =` as a cfg expression
-
-Caused by:
- expected a string, found nothing
-"));
-}
-
-#[test]
-fn multiple_match_ok() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [target.'cfg(unix)'.dependencies]
- b = {{ path = 'b' }}
- [target.'cfg(target_family = "unix")'.dependencies]
- b = {{ path = 'b' }}
- [target."cfg(windows)".dependencies]
- b = {{ path = 'b' }}
- [target.'cfg(target_family = "windows")'.dependencies]
- b = {{ path = 'b' }}
- [target."cfg(any(windows, unix))".dependencies]
- b = {{ path = 'b' }}
-
- [target.{}.dependencies]
- b = {{ path = 'b' }}
- "#, ::rustc_host()))
- .file("src/lib.rs", "extern crate b;")
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.0.1"
- authors = []
- "#)
- .file("b/src/lib.rs", "");
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn any_ok() {
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [target."cfg(any(windows, unix))".dependencies]
- b = { path = 'b' }
- "#)
- .file("src/lib.rs", "extern crate b;")
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.0.1"
- authors = []
- "#)
- .file("b/src/lib.rs", "");
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
-}
+++ /dev/null
-use std::env;
-
-use support::{git, project, execs, main_file, basic_bin_manifest};
-use support::registry::Package;
-use hamcrest::{assert_that, existing_dir, existing_file, is_not};
-
-#[test]
-fn cargo_clean_simple() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("build"), execs().with_status(0));
- assert_that(&p.build_dir(), existing_dir());
-
- assert_that(p.cargo("clean"),
- execs().with_status(0));
- assert_that(&p.build_dir(), is_not(existing_dir()));
-}
-
-#[test]
-fn different_dir() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
- .file("src/bar/a.rs", "");
-
- assert_that(p.cargo_process("build"), execs().with_status(0));
- assert_that(&p.build_dir(), existing_dir());
-
- assert_that(p.cargo("clean").cwd(&p.root().join("src")),
- execs().with_status(0).with_stdout(""));
- assert_that(&p.build_dir(), is_not(existing_dir()));
-}
-
-#[test]
-fn clean_multiple_packages() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.d1]
- path = "d1"
- [dependencies.d2]
- path = "d2"
-
- [[bin]]
- name = "foo"
- "#)
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
- .file("d1/Cargo.toml", r#"
- [package]
- name = "d1"
- version = "0.0.1"
- authors = []
-
- [[bin]]
- name = "d1"
- "#)
- .file("d1/src/main.rs", "fn main() { println!(\"d1\"); }")
- .file("d2/Cargo.toml", r#"
- [package]
- name = "d2"
- version = "0.0.1"
- authors = []
-
- [[bin]]
- name = "d2"
- "#)
- .file("d2/src/main.rs", "fn main() { println!(\"d2\"); }");
- p.build();
-
- assert_that(p.cargo_process("build").arg("-p").arg("d1").arg("-p").arg("d2")
- .arg("-p").arg("foo"),
- execs().with_status(0));
-
- let d1_path = &p.build_dir().join("debug").join("deps")
- .join(format!("d1{}", env::consts::EXE_SUFFIX));
- let d2_path = &p.build_dir().join("debug").join("deps")
- .join(format!("d2{}", env::consts::EXE_SUFFIX));
-
-
- assert_that(&p.bin("foo"), existing_file());
- assert_that(d1_path, existing_file());
- assert_that(d2_path, existing_file());
-
- assert_that(p.cargo("clean").arg("-p").arg("d1").arg("-p").arg("d2")
- .cwd(&p.root().join("src")),
- execs().with_status(0).with_stdout(""));
- assert_that(&p.bin("foo"), existing_file());
- assert_that(d1_path, is_not(existing_file()));
- assert_that(d2_path, is_not(existing_file()));
-}
-
-#[test]
-fn clean_release() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- a = { path = "a" }
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
- "#)
- .file("a/src/lib.rs", "");
- p.build();
-
- assert_that(p.cargo_process("build").arg("--release"),
- execs().with_status(0));
-
- assert_that(p.cargo("clean").arg("-p").arg("foo"),
- execs().with_status(0));
- assert_that(p.cargo("build").arg("--release"),
- execs().with_status(0).with_stdout(""));
-
- assert_that(p.cargo("clean").arg("-p").arg("foo").arg("--release"),
- execs().with_status(0));
- assert_that(p.cargo("build").arg("--release"),
- execs().with_status(0).with_stderr("\
-[COMPILING] foo v0.0.1 ([..])
-"));
-}
-
-#[test]
-fn build_script() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("build.rs", r#"
- use std::path::PathBuf;
- use std::env;
-
- fn main() {
- let out = PathBuf::from(env::var_os("OUT_DIR").unwrap());
- if env::var("FIRST").is_ok() {
- std::fs::File::create(out.join("out")).unwrap();
- } else {
- assert!(!std::fs::metadata(out.join("out")).is_ok());
- }
- }
- "#)
- .file("a/src/lib.rs", "");
- p.build();
-
- assert_that(p.cargo_process("build").env("FIRST", "1"),
- execs().with_status(0));
- assert_that(p.cargo("clean").arg("-p").arg("foo"),
- execs().with_status(0));
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-[COMPILING] foo v0.0.1 ([..])
-[RUNNING] `rustc build.rs [..]`
-[RUNNING] `[..]build-script-build[..]`
-[RUNNING] `rustc src[..]main.rs [..]`
-"));
-}
-
-#[test]
-fn clean_git() {
- let git = git::new("dep", |project| {
- project.file("Cargo.toml", r#"
- [project]
- name = "dep"
- version = "0.5.0"
- authors = []
- "#)
- .file("src/lib.rs", "")
- }).unwrap();
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- dep = {{ git = '{}' }}
- "#, git.url()))
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0));
- assert_that(p.cargo("clean").arg("-p").arg("dep"),
- execs().with_status(0).with_stdout(""));
- assert_that(p.cargo("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn registry() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "0.1"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("bar", "0.1.0").publish();
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0));
- assert_that(p.cargo("clean").arg("-p").arg("bar"),
- execs().with_status(0).with_stdout(""));
- assert_that(p.cargo("build"),
- execs().with_status(0));
-}
+++ /dev/null
-use std::env;
-use std::fs::{self, File};
-use std::io::prelude::*;
-use tempdir::TempDir;
-
-use support::{project, execs, main_file, basic_bin_manifest};
-use support::{ProjectBuilder};
-use hamcrest::{assert_that, existing_file, is_not};
-use support::paths::{CargoPathExt,root};
-use cargo::util::process;
-
-#[test]
-fn cargo_compile_simple() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("build"), execs());
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("i am foo\n"));
-}
-
-#[test]
-fn cargo_compile_manifest_path() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("build")
- .arg("--manifest-path").arg("foo/Cargo.toml")
- .cwd(p.root().parent().unwrap()),
- execs().with_status(0));
- assert_that(&p.bin("foo"), existing_file());
-}
-
-#[test]
-fn cargo_compile_with_invalid_manifest() {
- let p = project("foo")
- .file("Cargo.toml", "");
-
- assert_that(p.cargo_process("build"),
- execs()
- .with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- no `package` or `project` section found.
-"))
-}
-
-#[test]
-fn cargo_compile_with_invalid_manifest2() {
- let p = project("foo")
- .file("Cargo.toml", r"
- [project]
- foo = bar
- ");
-
- assert_that(p.cargo_process("build"),
- execs()
- .with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- could not parse input as TOML
-Cargo.toml:3:19-3:20 expected a value
-
-"))
-}
-
-#[test]
-fn cargo_compile_with_invalid_manifest3() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/Cargo.toml", "a = bar");
-
- assert_that(p.cargo_process("build").arg("--manifest-path")
- .arg("src/Cargo.toml"),
- execs()
- .with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- could not parse input as TOML\n\
-src[..]Cargo.toml:1:5-1:6 expected a value\n\n"))
-}
-
-#[test]
-fn cargo_compile_with_invalid_version() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- authors = []
- version = "1.0"
- "#);
-
- assert_that(p.cargo_process("build"),
- execs()
- .with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- cannot parse '1.0' as a semver for the key `project.version`
-"))
-
-}
-
-#[test]
-fn cargo_compile_with_invalid_package_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = ""
- authors = []
- version = "0.0.0"
- "#);
-
- assert_that(p.cargo_process("build"),
- execs()
- .with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- package name cannot be an empty string.
-"))
-}
-
-#[test]
-fn cargo_compile_with_invalid_bin_target_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.0"
-
- [[bin]]
- name = ""
- "#);
-
- assert_that(p.cargo_process("build"),
- execs()
- .with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- binary target names cannot be empty.
-"))
-}
-
-#[test]
-fn cargo_compile_with_forbidden_bin_target_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.0"
-
- [[bin]]
- name = "build"
- "#);
-
- assert_that(p.cargo_process("build"),
- execs()
- .with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- the binary target name `build` is forbidden
-"))
-}
-
-#[test]
-fn cargo_compile_with_invalid_lib_target_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.0"
-
- [lib]
- name = ""
- "#);
-
- assert_that(p.cargo_process("build"),
- execs()
- .with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- library target names cannot be empty.
-"))
-}
-
-#[test]
-fn cargo_compile_without_manifest() {
- let tmpdir = TempDir::new("cargo").unwrap();
- let p = ProjectBuilder::new("foo", tmpdir.path().to_path_buf());
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] could not find `Cargo.toml` in `[..]` or any parent directory
-"));
-}
-
-#[test]
-fn cargo_compile_with_invalid_code() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", "invalid rust code!");
-
- assert_that(p.cargo_process("build"),
- execs()
- .with_status(101)
- .with_stderr_contains("\
-src[..]foo.rs:1:1: 1:8 error: expected item[..]found `invalid`
-src[..]foo.rs:1 invalid rust code!
- ^~~~~~~
-")
- .with_stderr_contains("\
-[ERROR] Could not compile `foo`.
-
-To learn more, run the command again with --verbose.\n"));
- assert_that(&p.root().join("Cargo.lock"), existing_file());
-}
-
-#[test]
-fn cargo_compile_with_invalid_code_in_deps() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "../bar"
- [dependencies.baz]
- path = "../baz"
- "#)
- .file("src/main.rs", "invalid rust code!");
- let bar = project("bar")
- .file("Cargo.toml", &basic_bin_manifest("bar"))
- .file("src/lib.rs", "invalid rust code!");
- let baz = project("baz")
- .file("Cargo.toml", &basic_bin_manifest("baz"))
- .file("src/lib.rs", "invalid rust code!");
- bar.build();
- baz.build();
- assert_that(p.cargo_process("build"), execs().with_status(101));
-}
-
-#[test]
-fn cargo_compile_with_warnings_in_the_root_package() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", "fn main() {} fn dead() {}");
-
- assert_that(p.cargo_process("build"),
- execs()
- .with_stderr("\
-[COMPILING] foo [..]
-src[..]foo.rs:1:14: 1:26 warning: function is never used: `dead`, \
- #[warn(dead_code)] on by default
-src[..]foo.rs:1 fn main() {} fn dead() {}
-[..] ^~~~~~~~~~~~
-"));
-}
-
-#[test]
-fn cargo_compile_with_warnings_in_a_dep_package() {
- let mut p = project("foo");
-
- p = p
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
- path = "bar"
-
- [[bin]]
-
- name = "foo"
- "#)
- .file("src/foo.rs",
- &main_file(r#""{}", bar::gimme()"#, &["bar"]))
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib]
-
- name = "bar"
- "#)
- .file("bar/src/bar.rs", r#"
- pub fn gimme() -> &'static str {
- "test passed"
- }
-
- fn dead() {}
- "#);
-
- assert_that(p.cargo_process("build"),
- execs().with_stderr(&format!("\
-[COMPILING] bar v0.5.0 ({url}/bar)
-[..]warning: function is never used: `dead`[..]
-[..]fn dead() {{}}
-[..]^~~~~~~~~~~~
-[COMPILING] foo v0.5.0 ({url})
-", url = p.url())));
-
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(
- process(&p.bin("foo")),
- execs().with_stdout("test passed\n"));
-}
-
-#[test]
-fn cargo_compile_with_nested_deps_inferred() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
- path = 'bar'
-
- [[bin]]
- name = "foo"
- "#)
- .file("src/foo.rs",
- &main_file(r#""{}", bar::gimme()"#, &["bar"]))
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.baz]
- path = "../baz"
- "#)
- .file("bar/src/lib.rs", r#"
- extern crate baz;
-
- pub fn gimme() -> String {
- baz::gimme()
- }
- "#)
- .file("baz/Cargo.toml", r#"
- [project]
-
- name = "baz"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("baz/src/lib.rs", r#"
- pub fn gimme() -> String {
- "test passed".to_string()
- }
- "#);
-
- p.cargo_process("build")
- .exec_with_output()
- .unwrap();
-
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(
- process(&p.bin("foo")),
- execs().with_stdout("test passed\n"));
-}
-
-#[test]
-fn cargo_compile_with_nested_deps_correct_bin() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
- path = "bar"
-
- [[bin]]
- name = "foo"
- "#)
- .file("src/main.rs",
- &main_file(r#""{}", bar::gimme()"#, &["bar"]))
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.baz]
- path = "../baz"
- "#)
- .file("bar/src/lib.rs", r#"
- extern crate baz;
-
- pub fn gimme() -> String {
- baz::gimme()
- }
- "#)
- .file("baz/Cargo.toml", r#"
- [project]
-
- name = "baz"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("baz/src/lib.rs", r#"
- pub fn gimme() -> String {
- "test passed".to_string()
- }
- "#);
-
- p.cargo_process("build")
- .exec_with_output()
- .unwrap();
-
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(
- process(&p.bin("foo")),
- execs().with_stdout("test passed\n"));
-}
-
-#[test]
-fn cargo_compile_with_nested_deps_shorthand() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
- path = "bar"
-
- [[bin]]
-
- name = "foo"
- "#)
- .file("src/foo.rs",
- &main_file(r#""{}", bar::gimme()"#, &["bar"]))
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.baz]
- path = "../baz"
-
- [lib]
-
- name = "bar"
- "#)
- .file("bar/src/bar.rs", r#"
- extern crate baz;
-
- pub fn gimme() -> String {
- baz::gimme()
- }
- "#)
- .file("baz/Cargo.toml", r#"
- [project]
-
- name = "baz"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib]
-
- name = "baz"
- "#)
- .file("baz/src/baz.rs", r#"
- pub fn gimme() -> String {
- "test passed".to_string()
- }
- "#);
-
- p.cargo_process("build")
- .exec_with_output()
- .unwrap();
-
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(
- process(&p.bin("foo")),
- execs().with_stdout("test passed\n"));
-}
-
-#[test]
-fn cargo_compile_with_nested_deps_longhand() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
- path = "bar"
- version = "0.5.0"
-
- [[bin]]
-
- name = "foo"
- "#)
- .file("src/foo.rs",
- &main_file(r#""{}", bar::gimme()"#, &["bar"]))
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.baz]
- path = "../baz"
- version = "0.5.0"
-
- [lib]
-
- name = "bar"
- "#)
- .file("bar/src/bar.rs", r#"
- extern crate baz;
-
- pub fn gimme() -> String {
- baz::gimme()
- }
- "#)
- .file("baz/Cargo.toml", r#"
- [project]
-
- name = "baz"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib]
-
- name = "baz"
- "#)
- .file("baz/src/baz.rs", r#"
- pub fn gimme() -> String {
- "test passed".to_string()
- }
- "#);
-
- assert_that(p.cargo_process("build"), execs());
-
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("test passed\n"));
-}
-
-// Check that Cargo gives a sensible error if a dependency can't be found
-// because of a name mismatch.
-#[test]
-fn cargo_compile_with_dep_name_mismatch() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
-
- name = "foo"
- version = "0.0.1"
- authors = ["wycats@example.com"]
-
- [[bin]]
-
- name = "foo"
-
- [dependencies.notquitebar]
-
- path = "bar"
- "#)
- .file("src/foo.rs", &main_file(r#""i am foo""#, &["bar"]))
- .file("bar/Cargo.toml", &basic_bin_manifest("bar"))
- .file("bar/src/bar.rs", &main_file(r#""i am bar""#, &[]));
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr(&format!(
-r#"[ERROR] no matching package named `notquitebar` found (required by `foo`)
-location searched: {proj_dir}/bar
-version required: *
-"#, proj_dir = p.url())));
-}
-
-#[test]
-fn cargo_compile_with_filename() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file("src/bin/a.rs", r#"
- extern crate foo;
- fn main() { println!("hello a.rs"); }
- "#)
- .file("examples/a.rs", r#"
- fn main() { println!("example"); }
- "#);
-
- assert_that(p.cargo_process("build").arg("--bin").arg("bin.rs"),
- execs().with_status(101).with_stderr("\
-[ERROR] no bin target named `bin.rs`"));
-
- assert_that(p.cargo_process("build").arg("--bin").arg("a.rs"),
- execs().with_status(101).with_stderr("\
-[ERROR] no bin target named `a.rs`
-
-Did you mean `a`?"));
-
- assert_that(p.cargo_process("build").arg("--example").arg("example.rs"),
- execs().with_status(101).with_stderr("\
-[ERROR] no example target named `example.rs`"));
-
- assert_that(p.cargo_process("build").arg("--example").arg("a.rs"),
- execs().with_status(101).with_stderr("\
-[ERROR] no example target named `a.rs`
-
-Did you mean `a`?"));
-}
-
-#[test]
-fn compile_path_dep_then_change_version() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/lib.rs", "")
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", "");
-
- assert_that(p.cargo_process("build"), execs().with_status(0));
-
- File::create(&p.root().join("bar/Cargo.toml")).unwrap().write_all(br#"
- [package]
- name = "bar"
- version = "0.0.2"
- authors = []
- "#).unwrap();
-
- assert_that(p.cargo("build"),
- execs().with_status(101).with_stderr("\
-[ERROR] no matching package named `bar` found (required by `foo`)
-location searched: [..]
-version required: = 0.0.1
-versions found: 0.0.2
-consider running `cargo update` to update a path dependency's locked version
-"));
-}
-
-#[test]
-fn ignores_carriage_return_in_lockfile() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
- "#)
- .file("src/main.rs", r#"
- mod a; fn main() {}
- "#)
- .file("src/a.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0));
-
- let lockfile = p.root().join("Cargo.lock");
- let mut lock = String::new();
- File::open(&lockfile).unwrap().read_to_string(&mut lock).unwrap();
- let lock = lock.replace("\n", "\r\n");
- File::create(&lockfile).unwrap().write_all(lock.as_bytes()).unwrap();
- assert_that(p.cargo("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn crate_env_vars() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.1-alpha.1"
- description = "This is foo"
- homepage = "http://example.com"
- authors = ["wycats@example.com"]
- "#)
- .file("src/main.rs", r#"
- extern crate foo;
-
-
- static VERSION_MAJOR: &'static str = env!("CARGO_PKG_VERSION_MAJOR");
- static VERSION_MINOR: &'static str = env!("CARGO_PKG_VERSION_MINOR");
- static VERSION_PATCH: &'static str = env!("CARGO_PKG_VERSION_PATCH");
- static VERSION_PRE: &'static str = env!("CARGO_PKG_VERSION_PRE");
- static VERSION: &'static str = env!("CARGO_PKG_VERSION");
- static CARGO_MANIFEST_DIR: &'static str = env!("CARGO_MANIFEST_DIR");
- static PKG_NAME: &'static str = env!("CARGO_PKG_NAME");
- static HOMEPAGE: &'static str = env!("CARGO_PKG_HOMEPAGE");
- static DESCRIPTION: &'static str = env!("CARGO_PKG_DESCRIPTION");
-
- fn main() {
- let s = format!("{}-{}-{} @ {} in {}", VERSION_MAJOR,
- VERSION_MINOR, VERSION_PATCH, VERSION_PRE,
- CARGO_MANIFEST_DIR);
- assert_eq!(s, foo::version());
- println!("{}", s);
- assert_eq!("foo", PKG_NAME);
- assert_eq!("http://example.com", HOMEPAGE);
- assert_eq!("This is foo", DESCRIPTION);
- assert_eq!(s, VERSION);
- }
- "#)
- .file("src/lib.rs", r#"
- pub fn version() -> String {
- format!("{}-{}-{} @ {} in {}",
- env!("CARGO_PKG_VERSION_MAJOR"),
- env!("CARGO_PKG_VERSION_MINOR"),
- env!("CARGO_PKG_VERSION_PATCH"),
- env!("CARGO_PKG_VERSION_PRE"),
- env!("CARGO_MANIFEST_DIR"))
- }
- "#);
-
- println!("build");
- assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0));
-
- println!("bin");
- assert_that(process(&p.bin("foo")),
- execs().with_stdout(&format!("0-5-1 @ alpha.1 in {}\n",
- p.root().display())));
-
- println!("test");
- assert_that(p.cargo("test").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn crate_authors_env_vars() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.1-alpha.1"
- authors = ["wycats@example.com", "neikos@example.com"]
- "#)
- .file("src/main.rs", r#"
- extern crate foo;
-
- static AUTHORS: &'static str = env!("CARGO_PKG_AUTHORS");
-
- fn main() {
- let s = "wycats@example.com:neikos@example.com";
- assert_eq!(AUTHORS, foo::authors());
- println!("{}", AUTHORS);
- assert_eq!(s, AUTHORS);
- }
- "#)
- .file("src/lib.rs", r#"
- pub fn authors() -> String {
- format!("{}", env!("CARGO_PKG_AUTHORS"))
- }
- "#);
-
- println!("build");
- assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0));
-
- println!("bin");
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("wycats@example.com:neikos@example.com"));
-
- println!("test");
- assert_that(p.cargo("test").arg("-v"),
- execs().with_status(0));
-}
-
-// this is testing that src/<pkg-name>.rs still works (for now)
-#[test]
-fn many_crate_types_old_style_lib_location() {
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib]
-
- name = "foo"
- crate_type = ["rlib", "dylib"]
- "#)
- .file("src/foo.rs", r#"
- pub fn foo() {}
- "#);
- assert_that(p.cargo_process("build"), execs().with_status(0));
-
- assert_that(&p.root().join("target/debug/libfoo.rlib"), existing_file());
- let fname = format!("{}foo{}", env::consts::DLL_PREFIX,
- env::consts::DLL_SUFFIX);
- assert_that(&p.root().join("target/debug").join(&fname), existing_file());
-}
-
-#[test]
-fn many_crate_types_correct() {
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib]
-
- name = "foo"
- crate_type = ["rlib", "dylib"]
- "#)
- .file("src/lib.rs", r#"
- pub fn foo() {}
- "#);
- assert_that(p.cargo_process("build"),
- execs().with_status(0));
-
- assert_that(&p.root().join("target/debug/libfoo.rlib"), existing_file());
- let fname = format!("{}foo{}", env::consts::DLL_PREFIX,
- env::consts::DLL_SUFFIX);
- assert_that(&p.root().join("target/debug").join(&fname), existing_file());
-}
-
-#[test]
-fn unused_keys() {
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- bulid = "foo"
-
- [lib]
-
- name = "foo"
- "#)
- .file("src/foo.rs", r#"
- pub fn foo() {}
- "#);
- assert_that(p.cargo_process("build"),
- execs().with_status(0)
- .with_stderr("\
-warning: unused manifest key: project.bulid
-[COMPILING] foo [..]
-"));
-
- let mut p = project("bar");
- p = p
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib]
-
- name = "foo"
- build = "foo"
- "#)
- .file("src/foo.rs", r#"
- pub fn foo() {}
- "#);
- assert_that(p.cargo_process("build"),
- execs().with_status(0)
- .with_stderr("\
-warning: unused manifest key: lib.build
-[COMPILING] foo [..]
-"));
-}
-
-#[test]
-fn self_dependency() {
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [package]
-
- name = "test"
- version = "0.0.0"
- authors = []
-
- [dependencies.test]
-
- path = "."
-
- [lib]
-
- name = "test"
- "#)
- .file("src/test.rs", "fn main() {}");
- assert_that(p.cargo_process("build"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] cyclic package dependency: package `test v0.0.0 ([..])` depends on itself
-"));
-}
-
-#[test]
-fn ignore_broken_symlinks() {
- // windows and symlinks don't currently agree that well
- if cfg!(windows) { return }
-
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
- .symlink("Notafile", "bar");
-
- assert_that(p.cargo_process("build"), execs());
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("i am foo\n"));
-}
-
-#[test]
-fn missing_lib_and_bin() {
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [package]
-
- name = "test"
- version = "0.0.0"
- authors = []
- "#);
- assert_that(p.cargo_process("build"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]Cargo.toml`
-
-Caused by:
- no targets specified in the manifest
- either src/lib.rs, src/main.rs, a [lib] section, or [[bin]] section must be present\n"));
-}
-
-#[test]
-fn lto_build() {
- // FIXME: currently this hits a linker bug on 32-bit MSVC
- if cfg!(all(target_env = "msvc", target_pointer_width = "32")) {
- return
- }
-
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [package]
-
- name = "test"
- version = "0.0.0"
- authors = []
-
- [profile.release]
- lto = true
- "#)
- .file("src/main.rs", "fn main() {}");
- assert_that(p.cargo_process("build").arg("-v").arg("--release"),
- execs().with_status(0).with_stderr(&format!("\
-[COMPILING] test v0.0.0 ({url})
-[RUNNING] `rustc src[..]main.rs --crate-name test --crate-type bin \
- -C opt-level=3 \
- -C lto \
- --out-dir {dir}[..]target[..]release \
- --emit=dep-info,link \
- -L dependency={dir}[..]target[..]release \
- -L dependency={dir}[..]target[..]release[..]deps`
-",
-dir = p.root().display(),
-url = p.url(),
-)));
-}
-
-#[test]
-fn verbose_build() {
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [package]
-
- name = "test"
- version = "0.0.0"
- authors = []
- "#)
- .file("src/lib.rs", "");
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0).with_stderr(&format!("\
-[COMPILING] test v0.0.0 ({url})
-[RUNNING] `rustc src[..]lib.rs --crate-name test --crate-type lib -g \
- --out-dir {dir}[..]target[..]debug \
- --emit=dep-info,link \
- -L dependency={dir}[..]target[..]debug \
- -L dependency={dir}[..]target[..]debug[..]deps`
-",
-dir = p.root().display(),
-url = p.url(),
-)));
-}
-
-#[test]
-fn verbose_release_build() {
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [package]
-
- name = "test"
- version = "0.0.0"
- authors = []
- "#)
- .file("src/lib.rs", "");
- assert_that(p.cargo_process("build").arg("-v").arg("--release"),
- execs().with_status(0).with_stderr(&format!("\
-[COMPILING] test v0.0.0 ({url})
-[RUNNING] `rustc src[..]lib.rs --crate-name test --crate-type lib \
- -C opt-level=3 \
- --out-dir {dir}[..]target[..]release \
- --emit=dep-info,link \
- -L dependency={dir}[..]target[..]release \
- -L dependency={dir}[..]target[..]release[..]deps`
-",
-dir = p.root().display(),
-url = p.url(),
-)));
-}
-
-#[test]
-fn verbose_release_build_deps() {
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [package]
-
- name = "test"
- version = "0.0.0"
- authors = []
-
- [dependencies.foo]
- path = "foo"
- "#)
- .file("src/lib.rs", "")
- .file("foo/Cargo.toml", r#"
- [package]
-
- name = "foo"
- version = "0.0.0"
- authors = []
-
- [lib]
- name = "foo"
- crate_type = ["dylib", "rlib"]
- "#)
- .file("foo/src/lib.rs", "");
- assert_that(p.cargo_process("build").arg("-v").arg("--release"),
- execs().with_status(0).with_stderr(&format!("\
-[COMPILING] foo v0.0.0 ({url}/foo)
-[RUNNING] `rustc foo[..]src[..]lib.rs --crate-name foo \
- --crate-type dylib --crate-type rlib -C prefer-dynamic \
- -C opt-level=3 \
- -C metadata=[..] \
- -C extra-filename=-[..] \
- --out-dir {dir}[..]target[..]release[..]deps \
- --emit=dep-info,link \
- -L dependency={dir}[..]target[..]release[..]deps \
- -L dependency={dir}[..]target[..]release[..]deps`
-[COMPILING] test v0.0.0 ({url})
-[RUNNING] `rustc src[..]lib.rs --crate-name test --crate-type lib \
- -C opt-level=3 \
- --out-dir {dir}[..]target[..]release \
- --emit=dep-info,link \
- -L dependency={dir}[..]target[..]release \
- -L dependency={dir}[..]target[..]release[..]deps \
- --extern foo={dir}[..]target[..]release[..]deps[..]\
- {prefix}foo-[..]{suffix} \
- --extern foo={dir}[..]target[..]release[..]deps[..]libfoo-[..].rlib`
-",
- dir = p.root().display(),
- url = p.url(),
- prefix = env::consts::DLL_PREFIX,
- suffix = env::consts::DLL_SUFFIX)));
-}
-
-#[test]
-fn explicit_examples() {
- let mut p = project("world");
- p = p.file("Cargo.toml", r#"
- [package]
- name = "world"
- version = "1.0.0"
- authors = []
-
- [lib]
- name = "world"
- path = "src/lib.rs"
-
- [[example]]
- name = "hello"
- path = "examples/ex-hello.rs"
-
- [[example]]
- name = "goodbye"
- path = "examples/ex-goodbye.rs"
- "#)
- .file("src/lib.rs", r#"
- pub fn get_hello() -> &'static str { "Hello" }
- pub fn get_goodbye() -> &'static str { "Goodbye" }
- pub fn get_world() -> &'static str { "World" }
- "#)
- .file("examples/ex-hello.rs", r#"
- extern crate world;
- fn main() { println!("{}, {}!", world::get_hello(), world::get_world()); }
- "#)
- .file("examples/ex-goodbye.rs", r#"
- extern crate world;
- fn main() { println!("{}, {}!", world::get_goodbye(), world::get_world()); }
- "#);
-
- assert_that(p.cargo_process("test").arg("-v"), execs().with_status(0));
- assert_that(process(&p.bin("examples/hello")),
- execs().with_stdout("Hello, World!\n"));
- assert_that(process(&p.bin("examples/goodbye")),
- execs().with_stdout("Goodbye, World!\n"));
-}
-
-#[test]
-fn implicit_examples() {
- let mut p = project("world");
- p = p.file("Cargo.toml", r#"
- [package]
- name = "world"
- version = "1.0.0"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- pub fn get_hello() -> &'static str { "Hello" }
- pub fn get_goodbye() -> &'static str { "Goodbye" }
- pub fn get_world() -> &'static str { "World" }
- "#)
- .file("examples/hello.rs", r#"
- extern crate world;
- fn main() {
- println!("{}, {}!", world::get_hello(), world::get_world());
- }
- "#)
- .file("examples/goodbye.rs", r#"
- extern crate world;
- fn main() {
- println!("{}, {}!", world::get_goodbye(), world::get_world());
- }
- "#);
-
- assert_that(p.cargo_process("test"), execs().with_status(0));
- assert_that(process(&p.bin("examples/hello")),
- execs().with_stdout("Hello, World!\n"));
- assert_that(process(&p.bin("examples/goodbye")),
- execs().with_stdout("Goodbye, World!\n"));
-}
-
-#[test]
-fn standard_build_no_ndebug() {
- let p = project("world")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", r#"
- fn main() {
- if cfg!(debug_assertions) {
- println!("slow")
- } else {
- println!("fast")
- }
- }
- "#);
-
- assert_that(p.cargo_process("build"), execs().with_status(0));
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("slow\n"));
-}
-
-#[test]
-fn release_build_ndebug() {
- let p = project("world")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", r#"
- fn main() {
- if cfg!(debug_assertions) {
- println!("slow")
- } else {
- println!("fast")
- }
- }
- "#);
-
- assert_that(p.cargo_process("build").arg("--release"),
- execs().with_status(0));
- assert_that(process(&p.release_bin("foo")),
- execs().with_stdout("fast\n"));
-}
-
-#[test]
-fn inferred_main_bin() {
- let p = project("world")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#);
-
- assert_that(p.cargo_process("build"), execs().with_status(0));
- assert_that(process(&p.bin("foo")), execs().with_status(0));
-}
-
-#[test]
-fn deletion_causes_failure() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/main.rs", r#"
- extern crate bar;
- fn main() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", "");
-
- assert_that(p.cargo_process("build"), execs().with_status(0));
- let p = p.file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#);
- assert_that(p.cargo_process("build"), execs().with_status(101));
-}
-
-#[test]
-fn bad_cargo_toml_in_target_dir() {
- let p = project("world")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("target/Cargo.toml", "bad-toml");
-
- assert_that(p.cargo_process("build"), execs().with_status(0));
- assert_that(process(&p.bin("foo")), execs().with_status(0));
-}
-
-#[test]
-fn lib_with_standard_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "syntax"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "
- pub fn foo() {}
- ")
- .file("src/main.rs", "
- extern crate syntax;
- fn main() { syntax::foo() }
- ");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] syntax v0.0.1 ({dir})
-",
- dir = p.url())));
-}
-
-#[test]
-fn simple_staticlib() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
-
- [lib]
- name = "foo"
- crate-type = ["staticlib"]
- "#)
- .file("src/lib.rs", "pub fn foo() {}");
-
- // env var is a test for #1381
- assert_that(p.cargo_process("build").env("RUST_LOG", "nekoneko=trace"),
- execs().with_status(0));
-}
-
-#[test]
-fn staticlib_rlib_and_bin() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
-
- [lib]
- name = "foo"
- crate-type = ["staticlib", "rlib"]
- "#)
- .file("src/lib.rs", "pub fn foo() {}")
- .file("src/main.rs", r#"
- extern crate foo;
-
- fn main() {
- foo::foo();
- }"#);
-
- assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0));
-}
-
-#[test]
-fn opt_out_of_bin() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- bin = []
-
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
- "#)
- .file("src/lib.rs", "")
- .file("src/main.rs", "bad syntax");
- assert_that(p.cargo_process("build"), execs().with_status(0));
-}
-
-#[test]
-fn single_lib() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
-
- [lib]
- name = "foo"
- path = "src/bar.rs"
- "#)
- .file("src/bar.rs", "");
- assert_that(p.cargo_process("build"), execs().with_status(0));
-}
-
-#[test]
-fn freshness_ignores_excluded() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- build = "build.rs"
- exclude = ["src/b*.rs"]
- "#)
- .file("build.rs", "fn main() {}")
- .file("src/lib.rs", "pub fn bar() -> i32 { 1 }");
- foo.build();
- foo.root().move_into_the_past().unwrap();
-
- assert_that(foo.cargo("build"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.0 ({url})
-", url = foo.url())));
-
- // Smoke test to make sure it doesn't compile again
- println!("first pass");
- assert_that(foo.cargo("build"),
- execs().with_status(0)
- .with_stdout(""));
-
- // Modify an ignored file and make sure we don't rebuild
- println!("second pass");
- File::create(&foo.root().join("src/bar.rs")).unwrap();
- assert_that(foo.cargo("build"),
- execs().with_status(0)
- .with_stdout(""));
-}
-
-#[test]
-fn rebuild_preserves_out_dir() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- build = 'build.rs'
- "#)
- .file("build.rs", r#"
- use std::env;
- use std::fs::File;
- use std::path::Path;
-
- fn main() {
- let path = Path::new(&env::var("OUT_DIR").unwrap()).join("foo");
- if env::var_os("FIRST").is_some() {
- File::create(&path).unwrap();
- } else {
- File::create(&path).unwrap();
- }
- }
- "#)
- .file("src/lib.rs", "pub fn bar() -> i32 { 1 }");
- foo.build();
- foo.root().move_into_the_past().unwrap();
-
- assert_that(foo.cargo("build").env("FIRST", "1"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.0 ({url})
-", url = foo.url())));
-
- File::create(&foo.root().join("src/bar.rs")).unwrap();
- assert_that(foo.cargo("build"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.0 ({url})
-", url = foo.url())));
-}
-
-#[test]
-fn dep_no_libs() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.0"
- authors = []
- "#)
- .file("bar/src/main.rs", "");
- assert_that(foo.cargo_process("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn recompile_space_in_name() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
-
- [lib]
- name = "foo"
- path = "src/my lib.rs"
- "#)
- .file("src/my lib.rs", "");
- assert_that(foo.cargo_process("build"), execs().with_status(0));
- foo.root().move_into_the_past().unwrap();
- assert_that(foo.cargo("build"),
- execs().with_status(0).with_stdout(""));
-}
-
-#[cfg(unix)]
-#[test]
-fn ignore_bad_directories() {
- use std::os::unix::prelude::*;
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- "#)
- .file("src/lib.rs", "");
- foo.build();
- let dir = foo.root().join("tmp");
- fs::create_dir(&dir).unwrap();
- let stat = fs::metadata(&dir).unwrap();
- let mut perms = stat.permissions();
- perms.set_mode(0o644);
- fs::set_permissions(&dir, perms.clone()).unwrap();
- assert_that(foo.cargo("build"),
- execs().with_status(0));
- perms.set_mode(0o755);
- fs::set_permissions(&dir, perms).unwrap();
-}
-
-#[test]
-fn bad_cargo_config() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", r#"
- this is not valid toml
- "#);
- assert_that(foo.cargo_process("build").arg("-v"),
- execs().with_status(101).with_stderr("\
-[ERROR] Couldn't load Cargo configuration
-
-Caused by:
- could not parse TOML configuration in `[..]`
-
-Caused by:
- could not parse input as TOML
-[..].cargo[..]config:2:20-2:21 expected `=`, but found `i`
-
-"));
-}
-
-#[test]
-fn cargo_platform_specific_dependency() {
- let host = ::rustc_host();
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- build = "build.rs"
-
- [target.{host}.dependencies]
- dep = {{ path = "dep" }}
- [target.{host}.build-dependencies]
- build = {{ path = "build" }}
- [target.{host}.dev-dependencies]
- dev = {{ path = "dev" }}
- "#, host = host))
- .file("src/main.rs", r#"
- extern crate dep;
- fn main() { dep::dep() }
- "#)
- .file("tests/foo.rs", r#"
- extern crate dev;
- #[test]
- fn foo() { dev::dev() }
- "#)
- .file("build.rs", r#"
- extern crate build;
- fn main() { build::build(); }
- "#)
- .file("dep/Cargo.toml", r#"
- [project]
- name = "dep"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("dep/src/lib.rs", "pub fn dep() {}")
- .file("build/Cargo.toml", r#"
- [project]
- name = "build"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("build/src/lib.rs", "pub fn build() {}")
- .file("dev/Cargo.toml", r#"
- [project]
- name = "dev"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("dev/src/lib.rs", "pub fn dev() {}");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0));
-
- assert_that(&p.bin("foo"), existing_file());
- assert_that(p.cargo("test"),
- execs().with_status(0));
-}
-
-#[test]
-fn bad_platform_specific_dependency() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [target.wrong-target.dependencies.bar]
- path = "bar"
- "#)
- .file("src/main.rs",
- &main_file(r#""{}", bar::gimme()"#, &["bar"]))
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("bar/src/lib.rs", r#"
- extern crate baz;
-
- pub fn gimme() -> String {
- format!("")
- }
- "#);
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101));
-}
-
-#[test]
-fn cargo_platform_specific_dependency_wrong_platform() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [target.non-existing-triplet.dependencies.bar]
- path = "bar"
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("bar/src/lib.rs", r#"
- invalid rust file, should not be compiled
- "#);
-
- p.cargo_process("build").exec_with_output().unwrap();
-
- assert_that(&p.bin("foo"), existing_file());
- assert_that(process(&p.bin("foo")),
- execs());
-
- let loc = p.root().join("Cargo.lock");
- let mut lockfile = String::new();
- File::open(&loc).unwrap().read_to_string(&mut lockfile).unwrap();
- assert!(lockfile.contains("bar"))
-}
-
-#[test]
-fn example_bin_same_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("examples/foo.rs", "fn main() {}");
-
- p.cargo_process("test").arg("--no-run").arg("-v")
- .exec_with_output()
- .unwrap();
-
- assert_that(&p.bin("foo"), is_not(existing_file()));
- assert_that(&p.bin("examples/foo"), existing_file());
-
- p.cargo("test").arg("--no-run").arg("-v")
- .exec_with_output()
- .unwrap();
-
- assert_that(&p.bin("foo"), is_not(existing_file()));
- assert_that(&p.bin("examples/foo"), existing_file());
-}
-
-#[test]
-fn compile_then_delete() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("run"), execs().with_status(0));
- assert_that(&p.bin("foo"), existing_file());
- if cfg!(windows) {
- // On windows unlinking immediately after running often fails, so sleep
- ::sleep_ms(100);
- }
- fs::remove_file(&p.bin("foo")).unwrap();
- assert_that(p.cargo("run"),
- execs().with_status(0));
-}
-
-#[test]
-fn transitive_dependencies_not_available() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.aaaaa]
- path = "a"
- "#)
- .file("src/main.rs", "extern crate bbbbb; extern crate aaaaa; fn main() {}")
- .file("a/Cargo.toml", r#"
- [package]
- name = "aaaaa"
- version = "0.0.1"
- authors = []
-
- [dependencies.bbbbb]
- path = "../b"
- "#)
- .file("a/src/lib.rs", "extern crate bbbbb;")
- .file("b/Cargo.toml", r#"
- [package]
- name = "bbbbb"
- version = "0.0.1"
- authors = []
- "#)
- .file("b/src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(101)
- .with_stderr_contains("\
-[..] can't find crate for `bbbbb`[..]
-"));
-}
-
-#[test]
-fn cyclic_deps_rejected() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.a]
- path = "a"
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [dependencies.foo]
- path = ".."
- "#)
- .file("a/src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] cyclic package dependency: package `foo v0.0.1 ([..])` depends on itself
-"));
-}
-
-#[test]
-fn predictable_filenames() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo"
- crate-type = ["dylib", "rlib"]
- "#)
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
- assert_that(&p.root().join("target/debug/libfoo.rlib"), existing_file());
- let dylib_name = format!("{}foo{}", env::consts::DLL_PREFIX,
- env::consts::DLL_SUFFIX);
- assert_that(&p.root().join("target/debug").join(dylib_name),
- existing_file());
-}
-
-#[test]
-fn dashes_to_underscores() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo-bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file("src/main.rs", "extern crate foo_bar; fn main() {}");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
- assert_that(&p.bin("foo-bar"), existing_file());
-}
-
-#[test]
-fn dashes_in_crate_name_bad() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo-bar"
- "#)
- .file("src/lib.rs", "")
- .file("src/main.rs", "extern crate foo_bar; fn main() {}");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(101));
-}
-
-#[test]
-fn rustc_env_var() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "");
- p.build();
-
- assert_that(p.cargo("build")
- .env("RUSTC", "rustc-that-does-not-exist").arg("-v"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] Could not execute process `rustc-that-does-not-exist -vV` ([..])
-
-Caused by:
-[..]
-"));
- assert_that(&p.bin("a"), is_not(existing_file()));
-}
-
-#[test]
-fn filtering() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file("src/bin/a.rs", "fn main() {}")
- .file("src/bin/b.rs", "fn main() {}")
- .file("examples/a.rs", "fn main() {}")
- .file("examples/b.rs", "fn main() {}");
- p.build();
-
- assert_that(p.cargo("build").arg("--lib"),
- execs().with_status(0));
- assert_that(&p.bin("a"), is_not(existing_file()));
-
- assert_that(p.cargo("build").arg("--bin=a").arg("--example=a"),
- execs().with_status(0));
- assert_that(&p.bin("a"), existing_file());
- assert_that(&p.bin("b"), is_not(existing_file()));
- assert_that(&p.bin("examples/a"), existing_file());
- assert_that(&p.bin("examples/b"), is_not(existing_file()));
-}
-
-#[test]
-fn ignore_dotfile() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/bin/.a.rs", "")
- .file("src/bin/a.rs", "fn main() {}");
- p.build();
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn ignore_dotdirs() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/bin/a.rs", "fn main() {}")
- .file(".git/Cargo.toml", "")
- .file(".pc/dummy-fix.patch/Cargo.toml", "");
- p.build();
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn dotdir_root() {
- let p = ProjectBuilder::new("foo", root().join(".foo"))
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/bin/a.rs", "fn main() {}");
- p.build();
- assert_that(p.cargo("build"),
- execs().with_status(0));
-}
-
-
-#[test]
-fn custom_target_dir() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- let exe_name = format!("foo{}", env::consts::EXE_SUFFIX);
-
- assert_that(p.cargo("build").env("CARGO_TARGET_DIR", "foo/target"),
- execs().with_status(0));
- assert_that(&p.root().join("foo/target/debug").join(&exe_name),
- existing_file());
- assert_that(&p.root().join("target/debug").join(&exe_name),
- is_not(existing_file()));
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
- assert_that(&p.root().join("foo/target/debug").join(&exe_name),
- existing_file());
- assert_that(&p.root().join("target/debug").join(&exe_name),
- existing_file());
-
- fs::create_dir(p.root().join(".cargo")).unwrap();
- File::create(p.root().join(".cargo/config")).unwrap().write_all(br#"
- [build]
- target-dir = "foo/target"
- "#).unwrap();
- assert_that(p.cargo("build").env("CARGO_TARGET_DIR", "bar/target"),
- execs().with_status(0));
- assert_that(&p.root().join("bar/target/debug").join(&exe_name),
- existing_file());
- assert_that(&p.root().join("foo/target/debug").join(&exe_name),
- existing_file());
- assert_that(&p.root().join("target/debug").join(&exe_name),
- existing_file());
-}
-
-#[test]
-fn rustc_no_trans() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- assert_that(p.cargo("rustc").arg("-v").arg("--").arg("-Zno-trans"),
- execs().with_status(0));
-}
-
-#[test]
-fn build_multiple_packages() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.d1]
- path = "d1"
- [dependencies.d2]
- path = "d2"
-
- [[bin]]
- name = "foo"
- "#)
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
- .file("d1/Cargo.toml", r#"
- [package]
- name = "d1"
- version = "0.0.1"
- authors = []
-
- [[bin]]
- name = "d1"
- "#)
- .file("d1/src/lib.rs", "")
- .file("d1/src/main.rs", "fn main() { println!(\"d1\"); }")
- .file("d2/Cargo.toml", r#"
- [package]
- name = "d2"
- version = "0.0.1"
- authors = []
-
- [[bin]]
- name = "d2"
- doctest = false
- "#)
- .file("d2/src/main.rs", "fn main() { println!(\"d2\"); }");
- p.build();
-
- assert_that(p.cargo_process("build").arg("-p").arg("d1").arg("-p").arg("d2")
- .arg("-p").arg("foo"),
- execs());
-
- assert_that(&p.bin("foo"), existing_file());
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("i am foo\n"));
-
- let d1_path = &p.build_dir().join("debug").join("deps")
- .join(format!("d1{}", env::consts::EXE_SUFFIX));
- let d2_path = &p.build_dir().join("debug").join("deps")
- .join(format!("d2{}", env::consts::EXE_SUFFIX));
-
- assert_that(d1_path, existing_file());
- assert_that(process(d1_path), execs().with_stdout("d1"));
-
- assert_that(d2_path, existing_file());
- assert_that(process(d2_path),
- execs().with_stdout("d2"));
-}
-
-#[test]
-fn invalid_spec() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.d1]
- path = "d1"
-
- [[bin]]
- name = "foo"
- "#)
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
- .file("d1/Cargo.toml", r#"
- [package]
- name = "d1"
- version = "0.0.1"
- authors = []
-
- [[bin]]
- name = "d1"
- "#)
- .file("d1/src/lib.rs", "")
- .file("d1/src/main.rs", "fn main() { println!(\"d1\"); }");
- p.build();
-
- assert_that(p.cargo_process("build").arg("-p").arg("notAValidDep"),
- execs().with_status(101).with_stderr("\
-[ERROR] package id specification `notAValidDep` matched no packages
-"));
-
- assert_that(p.cargo_process("build").arg("-p").arg("d1").arg("-p").arg("notAValidDep"),
- execs().with_status(101).with_stderr("\
-[ERROR] package id specification `notAValidDep` matched no packages
-"));
-}
-
-#[test]
-fn manifest_with_bom_is_ok() {
- let p = project("foo")
- .file("Cargo.toml", "\u{FEFF}
- [package]
- name = \"foo\"
- version = \"0.0.1\"
- authors = []
- ")
- .file("src/lib.rs", "");
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn panic_abort_compiles_with_panic_abort() {
- if !::is_nightly() {
- return
- }
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [profile.dev]
- panic = 'abort'
- "#)
- .file("src/lib.rs", "");
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0)
- .with_stderr_contains("[..] -C panic=abort [..]"));
-}
+++ /dev/null
-use std::fs::{self, File};
-use std::io::prelude::*;
-
-use support::{project, execs};
-use support::paths::CargoPathExt;
-use hamcrest::{assert_that, existing_file, existing_dir};
-
-#[test]
-fn custom_build_script_failed() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- build = "build.rs"
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("build.rs", r#"
- fn main() {
- std::process::exit(101);
- }
- "#);
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(101)
- .with_stderr(&format!("\
-[COMPILING] foo v0.5.0 ({url})
-[RUNNING] `rustc build.rs --crate-name build_script_build --crate-type bin [..]`
-[RUNNING] `[..]build-script-build[..]`
-[ERROR] failed to run custom build command for `foo v0.5.0 ({url})`
-Process didn't exit successfully: `[..]build[..]build-script-build[..]` \
- (exit code: 101)",
-url = p.url())));
-}
-
-#[test]
-fn custom_build_env_vars() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [features]
- bar_feat = ["bar/foo"]
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- build = "build.rs"
-
- [features]
- foo = []
- "#)
- .file("bar/src/lib.rs", r#"
- pub fn hello() {}
- "#);
-
- let file_content = format!(r#"
- use std::env;
- use std::io::prelude::*;
- use std::path::Path;
- use std::fs;
-
- fn main() {{
- let _target = env::var("TARGET").unwrap();
- let _ncpus = env::var("NUM_JOBS").unwrap();
- let _dir = env::var("CARGO_MANIFEST_DIR").unwrap();
-
- let opt = env::var("OPT_LEVEL").unwrap();
- assert_eq!(opt, "0");
-
- let opt = env::var("PROFILE").unwrap();
- assert_eq!(opt, "debug");
-
- let debug = env::var("DEBUG").unwrap();
- assert_eq!(debug, "true");
-
- let out = env::var("OUT_DIR").unwrap();
- assert!(out.starts_with(r"{0}"));
- assert!(fs::metadata(&out).map(|m| m.is_dir()).unwrap_or(false));
-
- let _host = env::var("HOST").unwrap();
-
- let _feat = env::var("CARGO_FEATURE_FOO").unwrap();
- }}
- "#,
- p.root().join("target").join("debug").join("build").display());
-
- let p = p.file("bar/build.rs", &file_content);
-
-
- assert_that(p.cargo_process("build").arg("--features").arg("bar_feat"),
- execs().with_status(0));
-}
-
-#[test]
-fn custom_build_script_wrong_rustc_flags() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- build = "build.rs"
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("build.rs", r#"
- fn main() {
- println!("cargo:rustc-flags=-aaa -bbb");
- }
- "#);
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101)
- .with_stderr_contains(&format!("\
-[ERROR] Only `-l` and `-L` flags are allowed in build script of `foo v0.5.0 ({})`: \
-`-aaa -bbb`",
-p.url())));
-}
-
-/*
-#[test]
-fn custom_build_script_rustc_flags() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.foo]
- path = "foo"
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("foo/Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- build = "build.rs"
- "#)
- .file("foo/src/lib.rs", r#"
- "#)
- .file("foo/build.rs", r#"
- fn main() {
- println!("cargo:rustc-flags=-l nonexistinglib -L /dummy/path1 -L /dummy/path2");
- }
- "#);
-
- // TODO: TEST FAILS BECAUSE OF WRONG STDOUT (but otherwise, the build works)
- assert_that(p.cargo_process("build").arg("--verbose"),
- execs().with_status(101)
- .with_stderr(&format!("\
-[COMPILING] bar v0.5.0 ({url})
-[RUNNING] `rustc {dir}{sep}src{sep}lib.rs --crate-name test --crate-type lib -g \
- -C metadata=[..] \
- -C extra-filename=-[..] \
- --out-dir {dir}{sep}target \
- --emit=dep-info,link \
- -L {dir}{sep}target \
- -L {dir}{sep}target{sep}deps`
-", sep = path::SEP,
-dir = p.root().display(),
-url = p.url(),
-)));
-}
-*/
-
-#[test]
-fn links_no_build_cmd() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- links = "a"
- "#)
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] package `foo v0.5.0 (file://[..])` specifies that it links to `a` but does \
-not have a custom build script
-"));
-}
-
-#[test]
-fn links_duplicates() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- links = "a"
- build = "build.rs"
-
- [dependencies.a]
- path = "a"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", "")
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- links = "a"
- build = "build.rs"
- "#)
- .file("a/src/lib.rs", "")
- .file("a/build.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] native library `a` is being linked to by more than one package, and can only be \
-linked to by one package
-
- [..] v0.5.0 (file://[..])
- [..] v0.5.0 (file://[..])
-"));
-}
-
-#[test]
-fn overrides_and_links() {
- let target = ::rustc_host();
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
-
- [dependencies.a]
- path = "a"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- use std::env;
- fn main() {
- assert_eq!(env::var("DEP_FOO_FOO").ok().expect("FOO missing"),
- "bar");
- assert_eq!(env::var("DEP_FOO_BAR").ok().expect("BAR missing"),
- "baz");
- }
- "#)
- .file(".cargo/config", &format!(r#"
- [target.{}.foo]
- rustc-flags = "-L foo -L bar"
- foo = "bar"
- bar = "baz"
- "#, target))
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- links = "foo"
- build = "build.rs"
- "#)
- .file("a/src/lib.rs", "")
- .file("a/build.rs", "not valid rust code");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0)
- .with_stderr("\
-[..]
-[..]
-[..]
-[..]
-[..]
-[RUNNING] `rustc [..] --crate-name foo [..] -L foo -L bar[..]`
-"));
-}
-
-#[test]
-fn unused_overrides() {
- let target = ::rustc_host();
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", "fn main() {}")
- .file(".cargo/config", &format!(r#"
- [target.{}.foo]
- rustc-flags = "-L foo -L bar"
- foo = "bar"
- bar = "baz"
- "#, target));
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn links_passes_env_vars() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
-
- [dependencies.a]
- path = "a"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- use std::env;
- fn main() {
- assert_eq!(env::var("DEP_FOO_FOO").unwrap(), "bar");
- assert_eq!(env::var("DEP_FOO_BAR").unwrap(), "baz");
- }
- "#)
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- links = "foo"
- build = "build.rs"
- "#)
- .file("a/src/lib.rs", "")
- .file("a/build.rs", r#"
- use std::env;
- fn main() {
- let lib = env::var("CARGO_MANIFEST_LINKS").unwrap();
- assert_eq!(lib, "foo");
-
- println!("cargo:foo=bar");
- println!("cargo:bar=baz");
- }
- "#);
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn only_rerun_build_script() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() {}
- "#);
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
- p.root().move_into_the_past().unwrap();
-
- File::create(&p.root().join("some-new-file")).unwrap();
- p.root().move_into_the_past().unwrap();
-
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] foo v0.5.0 (file://[..])
-[RUNNING] `[..]build-script-build[..]`
-[RUNNING] `rustc [..] --crate-name foo [..]`
-"));
-}
-
-#[test]
-fn rebuild_continues_to_pass_env_vars() {
- let a = project("a")
- .file("Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- links = "foo"
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- use std::time::Duration;
- fn main() {
- println!("cargo:foo=bar");
- println!("cargo:bar=baz");
- std::thread::sleep(Duration::from_millis(500));
- }
- "#);
- a.build();
- a.root().move_into_the_past().unwrap();
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
-
- [dependencies.a]
- path = '{}'
- "#, a.root().display()))
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- use std::env;
- fn main() {
- assert_eq!(env::var("DEP_FOO_FOO").unwrap(), "bar");
- assert_eq!(env::var("DEP_FOO_BAR").unwrap(), "baz");
- }
- "#);
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
- p.root().move_into_the_past().unwrap();
-
- File::create(&p.root().join("some-new-file")).unwrap();
- p.root().move_into_the_past().unwrap();
-
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn testing_and_such() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() {}
- "#);
-
- println!("build");
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
- p.root().move_into_the_past().unwrap();
-
- File::create(&p.root().join("src/lib.rs")).unwrap();
- p.root().move_into_the_past().unwrap();
-
- println!("test");
- assert_that(p.cargo("test").arg("-vj1"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] foo v0.5.0 (file://[..])
-[RUNNING] `[..]build-script-build[..]`
-[RUNNING] `rustc [..] --crate-name foo [..]`
-[RUNNING] `rustc [..] --crate-name foo [..]`
-[RUNNING] `[..]foo-[..][..]`
-[DOCTEST] foo
-[RUNNING] `rustdoc --test [..]`")
- .with_stdout("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-
- println!("doc");
- assert_that(p.cargo("doc").arg("-v"),
- execs().with_status(0)
- .with_stderr("\
-[DOCUMENTING] foo v0.5.0 (file://[..])
-[RUNNING] `rustdoc [..]`
-"));
-
- File::create(&p.root().join("src/main.rs")).unwrap()
- .write_all(b"fn main() {}").unwrap();
- println!("run");
- assert_that(p.cargo("run"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] foo v0.5.0 (file://[..])
-[RUNNING] `target[..]foo[..]`
-"));
-}
-
-#[test]
-fn propagation_of_l_flags() {
- let target = ::rustc_host();
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- [dependencies.a]
- path = "a"
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- links = "bar"
- build = "build.rs"
-
- [dependencies.b]
- path = "../b"
- "#)
- .file("a/src/lib.rs", "")
- .file("a/build.rs", r#"
- fn main() {
- println!("cargo:rustc-flags=-L bar");
- }
- "#)
- .file("b/Cargo.toml", r#"
- [project]
- name = "b"
- version = "0.5.0"
- authors = []
- links = "foo"
- build = "build.rs"
- "#)
- .file("b/src/lib.rs", "")
- .file("b/build.rs", "bad file")
- .file(".cargo/config", &format!(r#"
- [target.{}.foo]
- rustc-flags = "-L foo"
- "#, target));
-
- assert_that(p.cargo_process("build").arg("-v").arg("-j1"),
- execs().with_status(0)
- .with_stderr_contains("\
-[RUNNING] `rustc [..] --crate-name a [..]-L bar[..]-L foo[..]`
-[COMPILING] foo v0.5.0 (file://[..])
-[RUNNING] `rustc [..] --crate-name foo [..] -L bar -L foo`
-"));
-}
-
-#[test]
-fn propagation_of_l_flags_new() {
- let target = ::rustc_host();
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- [dependencies.a]
- path = "a"
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- links = "bar"
- build = "build.rs"
-
- [dependencies.b]
- path = "../b"
- "#)
- .file("a/src/lib.rs", "")
- .file("a/build.rs", r#"
- fn main() {
- println!("cargo:rustc-link-search=bar");
- }
- "#)
- .file("b/Cargo.toml", r#"
- [project]
- name = "b"
- version = "0.5.0"
- authors = []
- links = "foo"
- build = "build.rs"
- "#)
- .file("b/src/lib.rs", "")
- .file("b/build.rs", "bad file")
- .file(".cargo/config", &format!(r#"
- [target.{}.foo]
- rustc-link-search = ["foo"]
- "#, target));
-
- assert_that(p.cargo_process("build").arg("-v").arg("-j1"),
- execs().with_status(0)
- .with_stderr_contains("\
-[RUNNING] `rustc [..] --crate-name a [..]-L bar[..]-L foo[..]`
-[COMPILING] foo v0.5.0 (file://[..])
-[RUNNING] `rustc [..] --crate-name foo [..] -L bar -L foo`
-"));
-}
-
-#[test]
-fn build_deps_simple() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- [build-dependencies.a]
- path = "a"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", "
- extern crate a;
- fn main() {}
- ")
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- "#)
- .file("a/src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] a v0.5.0 (file://[..])
-[RUNNING] `rustc [..] --crate-name a [..]`
-[COMPILING] foo v0.5.0 (file://[..])
-[RUNNING] `rustc build.rs [..] --extern a=[..]`
-[RUNNING] `[..]foo-[..]build-script-build[..]`
-[RUNNING] `rustc [..] --crate-name foo [..]`
-"));
-}
-
-#[test]
-fn build_deps_not_for_normal() {
- let target = ::rustc_host();
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- [build-dependencies.aaaaa]
- path = "a"
- "#)
- .file("src/lib.rs", "extern crate aaaaa;")
- .file("build.rs", "
- extern crate aaaaa;
- fn main() {}
- ")
- .file("a/Cargo.toml", r#"
- [project]
- name = "aaaaa"
- version = "0.5.0"
- authors = []
- "#)
- .file("a/src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v").arg("--target").arg(&target),
- execs().with_status(101)
- .with_stderr_contains("\
-[..]lib.rs[..] error: can't find crate for `aaaaa`[..]
-[..]lib.rs[..] extern crate aaaaa;
-[..] ^~~~~~~~~~~~~~~~~~~
-error: aborting due to previous error
-[ERROR] Could not compile `foo`.
-
-Caused by:
- Process didn't exit successfully: [..]
-"));
-}
-
-#[test]
-fn build_cmd_with_a_build_cmd() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
-
- [build-dependencies.a]
- path = "a"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", "
- extern crate a;
- fn main() {}
- ")
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- build = "build.rs"
-
- [build-dependencies.b]
- path = "../b"
- "#)
- .file("a/src/lib.rs", "")
- .file("a/build.rs", "extern crate b; fn main() {}")
- .file("b/Cargo.toml", r#"
- [project]
- name = "b"
- version = "0.5.0"
- authors = []
- "#)
- .file("b/src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] b v0.5.0 (file://[..])
-[RUNNING] `rustc [..] --crate-name b [..]`
-[COMPILING] a v0.5.0 (file://[..])
-[RUNNING] `rustc a[..]build.rs [..] --extern b=[..]`
-[RUNNING] `[..]a-[..]build-script-build[..]`
-[RUNNING] `rustc [..]lib.rs --crate-name a --crate-type lib -g \
- -C metadata=[..] -C extra-filename=-[..] \
- --out-dir [..]target[..]deps --emit=dep-info,link \
- -L [..]target[..]deps -L [..]target[..]deps`
-[COMPILING] foo v0.5.0 (file://[..])
-[RUNNING] `rustc build.rs --crate-name build_script_build --crate-type bin \
- -g \
- --out-dir [..]build[..]foo-[..] --emit=dep-info,link \
- -L [..]target[..]debug -L [..]target[..]deps \
- --extern a=[..]liba-[..].rlib`
-[RUNNING] `[..]foo-[..]build-script-build[..]`
-[RUNNING] `rustc [..]lib.rs --crate-name foo --crate-type lib -g \
- --out-dir [..]target[..]debug --emit=dep-info,link \
- -L [..]target[..]debug -L [..]target[..]deps`
-"));
-}
-
-#[test]
-fn out_dir_is_preserved() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- use std::env;
- use std::fs::File;
- use std::path::Path;
- fn main() {
- let out = env::var("OUT_DIR").unwrap();
- File::create(Path::new(&out).join("foo")).unwrap();
- }
- "#);
-
- // Make the file
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
- p.root().move_into_the_past().unwrap();
-
- // Change to asserting that it's there
- File::create(&p.root().join("build.rs")).unwrap().write_all(br#"
- use std::env;
- use std::old_io::File;
- fn main() {
- let out = env::var("OUT_DIR").unwrap();
- File::open(&Path::new(&out).join("foo")).unwrap();
- }
- "#).unwrap();
- p.root().move_into_the_past().unwrap();
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0));
-
- // Run a fresh build where file should be preserved
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0));
-
- // One last time to make sure it's still there.
- File::create(&p.root().join("foo")).unwrap();
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn output_separate_lines() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() {
- println!("cargo:rustc-flags=-L foo");
- println!("cargo:rustc-flags=-l static=foo");
- }
- "#);
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(101)
- .with_stderr_contains("\
-[COMPILING] foo v0.5.0 (file://[..])
-[RUNNING] `rustc build.rs [..]`
-[RUNNING] `[..]foo-[..]build-script-build[..]`
-[RUNNING] `rustc [..] --crate-name foo [..] -L foo -l static=foo`
-[ERROR] could not find native static library [..]
-[ERROR] Could not compile [..]
-"));
-}
-
-#[test]
-fn output_separate_lines_new() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() {
- println!("cargo:rustc-link-search=foo");
- println!("cargo:rustc-link-lib=static=foo");
- }
- "#);
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(101)
- .with_stderr_contains("\
-[COMPILING] foo v0.5.0 (file://[..])
-[RUNNING] `rustc build.rs [..]`
-[RUNNING] `[..]foo-[..]build-script-build[..]`
-[RUNNING] `rustc [..] --crate-name foo [..] -L foo -l static=foo`
-[ERROR] could not find native static library [..]
-[ERROR] Could not compile [..]
-"));
-}
-
-#[cfg(not(windows))] // FIXME(#867)
-#[test]
-fn code_generation() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("src/main.rs", r#"
- include!(concat!(env!("OUT_DIR"), "/hello.rs"));
-
- fn main() {
- println!("{}", message());
- }
- "#)
- .file("build.rs", r#"
- use std::env;
- use std::fs::File;
- use std::io::prelude::*;
- use std::path::PathBuf;
-
- fn main() {
- let dst = PathBuf::from(env::var("OUT_DIR").unwrap());
- let mut f = File::create(&dst.join("hello.rs")).unwrap();
- f.write_all(b"
- pub fn message() -> &'static str {
- \"Hello, World!\"
- }
- ").unwrap();
- }
- "#);
- assert_that(p.cargo_process("run"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] foo v0.5.0 (file://[..])
-[RUNNING] `target[..]foo`")
- .with_stdout("\
-Hello, World!
-"));
-
- assert_that(p.cargo_process("test"),
- execs().with_status(0));
-}
-
-#[test]
-fn release_with_build_script() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() {}
- "#);
-
- assert_that(p.cargo_process("build").arg("-v").arg("--release"),
- execs().with_status(0));
-}
-
-#[test]
-fn build_script_only() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.0"
- authors = []
- build = "build.rs"
- "#)
- .file("build.rs", r#"fn main() {}"#);
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- no targets specified in the manifest
- either src/lib.rs, src/main.rs, a [lib] section, or [[bin]] section must be present"));
-}
-
-#[test]
-fn shared_dep_with_a_build_script() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
-
- [dependencies.a]
- path = "a"
-
- [build-dependencies.b]
- path = "b"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", "fn main() {}")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("a/build.rs", "fn main() {}")
- .file("a/src/lib.rs", "")
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.5.0"
- authors = []
-
- [dependencies.a]
- path = "../a"
- "#)
- .file("b/src/lib.rs", "");
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn transitive_dep_host() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
-
- [build-dependencies.b]
- path = "b"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", "fn main() {}")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.5.0"
- authors = []
- links = "foo"
- build = "build.rs"
- "#)
- .file("a/build.rs", "fn main() {}")
- .file("a/src/lib.rs", "")
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.5.0"
- authors = []
-
- [lib]
- name = "b"
- plugin = true
-
- [dependencies.a]
- path = "../a"
- "#)
- .file("b/src/lib.rs", "");
- assert_that(p.cargo_process("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn test_a_lib_with_a_build_command() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("src/lib.rs", r#"
- include!(concat!(env!("OUT_DIR"), "/foo.rs"));
-
- /// ```
- /// foo::bar();
- /// ```
- pub fn bar() {
- assert_eq!(foo(), 1);
- }
- "#)
- .file("build.rs", r#"
- use std::env;
- use std::io::prelude::*;
- use std::fs::File;
- use std::path::PathBuf;
-
- fn main() {
- let out = PathBuf::from(env::var("OUT_DIR").unwrap());
- File::create(out.join("foo.rs")).unwrap().write_all(b"
- fn foo() -> i32 { 1 }
- ").unwrap();
- }
- "#);
- assert_that(p.cargo_process("test"),
- execs().with_status(0));
-}
-
-#[test]
-fn test_dev_dep_build_script() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
-
- [dev-dependencies.a]
- path = "a"
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("a/build.rs", "fn main() {}")
- .file("a/src/lib.rs", "");
-
- assert_that(p.cargo_process("test"), execs().with_status(0));
-}
-
-#[test]
-fn build_script_with_dynamic_native_dependency() {
- let build = project("builder")
- .file("Cargo.toml", r#"
- [package]
- name = "builder"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "builder"
- crate-type = ["dylib"]
- plugin = true
- "#)
- .file("src/lib.rs", r#"
- #[no_mangle]
- pub extern fn foo() {}
- "#);
- assert_that(build.cargo_process("build"),
- execs().with_status(0));
-
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
-
- [build-dependencies.bar]
- path = "bar"
- "#)
- .file("build.rs", r#"
- extern crate bar;
- fn main() { bar::bar() }
- "#)
- .file("src/lib.rs", "")
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- "#)
- .file("bar/build.rs", r#"
- use std::env;
- use std::path::PathBuf;
-
- fn main() {
- let src = PathBuf::from(env::var("SRC").unwrap());
- println!("cargo:rustc-link-search={}/target/debug",
- src.display());
- }
- "#)
- .file("bar/src/lib.rs", r#"
- pub fn bar() {
- #[cfg_attr(not(target_env = "msvc"), link(name = "builder"))]
- #[cfg_attr(target_env = "msvc", link(name = "builder.dll"))]
- extern { fn foo(); }
- unsafe { foo() }
- }
- "#);
-
- assert_that(foo.cargo_process("build").env("SRC", build.root()),
- execs().with_status(0));
-}
-
-#[test]
-fn profile_and_opt_level_set_correctly() {
- let build = project("builder")
- .file("Cargo.toml", r#"
- [package]
- name = "builder"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- use std::env;
-
- fn main() {
- assert_eq!(env::var("OPT_LEVEL").unwrap(), "3");
- assert_eq!(env::var("PROFILE").unwrap(), "release");
- assert_eq!(env::var("DEBUG").unwrap(), "false");
- }
- "#);
- assert_that(build.cargo_process("bench"),
- execs().with_status(0));
-}
-
-#[test]
-fn build_script_with_lto() {
- let build = project("builder")
- .file("Cargo.toml", r#"
- [package]
- name = "builder"
- version = "0.0.1"
- authors = []
- build = "build.rs"
-
- [profile.dev]
- lto = true
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() {
- }
- "#);
- assert_that(build.cargo_process("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn test_duplicate_deps() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.1.0"
- authors = []
- build = "build.rs"
-
- [dependencies.bar]
- path = "bar"
-
- [build-dependencies.bar]
- path = "bar"
- "#)
- .file("src/main.rs", r#"
- extern crate bar;
- fn main() { bar::do_nothing() }
- "#)
- .file("build.rs", r#"
- extern crate bar;
- fn main() { bar::do_nothing() }
- "#)
- .file("bar/Cargo.toml", r#"
- [project]
- name = "bar"
- version = "0.1.0"
- authors = []
- "#)
- .file("bar/src/lib.rs", "pub fn do_nothing() {}");
-
- assert_that(p.cargo_process("build"), execs().with_status(0));
-}
-
-#[test]
-fn cfg_feedback() {
- let build = project("builder")
- .file("Cargo.toml", r#"
- [package]
- name = "builder"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- "#)
- .file("src/main.rs", "
- #[cfg(foo)]
- fn main() {}
- ")
- .file("build.rs", r#"
- fn main() {
- println!("cargo:rustc-cfg=foo");
- }
- "#);
- assert_that(build.cargo_process("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn cfg_override() {
- let target = ::rustc_host();
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- links = "a"
- build = "build.rs"
- "#)
- .file("src/main.rs", "
- #[cfg(foo)]
- fn main() {}
- ")
- .file("build.rs", "")
- .file(".cargo/config", &format!(r#"
- [target.{}.a]
- rustc-cfg = ["foo"]
- "#, target));
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn cfg_test() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- "#)
- .file("build.rs", r#"
- fn main() {
- println!("cargo:rustc-cfg=foo");
- }
- "#)
- .file("src/lib.rs", r#"
- ///
- /// ```
- /// extern crate foo;
- ///
- /// fn main() {
- /// foo::foo()
- /// }
- /// ```
- ///
- #[cfg(foo)]
- pub fn foo() {}
-
- #[cfg(foo)]
- #[test]
- fn test_foo() {
- foo()
- }
- "#)
- .file("tests/test.rs", r#"
- #[cfg(foo)]
- #[test]
- fn test_bar() {}
- "#);
- assert_that(p.cargo_process("test").arg("-v"),
- execs().with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] [..] build.rs [..]
-[RUNNING] [..]build-script-build[..]
-[RUNNING] [..] --cfg foo[..]
-[RUNNING] [..] --cfg foo[..]
-[RUNNING] [..] --cfg foo[..]
-[RUNNING] [..]foo-[..]
-[RUNNING] [..]test-[..]
-[DOCTEST] foo
-[RUNNING] [..] --cfg foo[..]", dir = p.url()))
- .with_stdout("
-running 1 test
-test test_foo ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test test_bar ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test foo_0 ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn cfg_doc() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("build.rs", r#"
- fn main() {
- println!("cargo:rustc-cfg=foo");
- }
- "#)
- .file("src/lib.rs", r#"
- #[cfg(foo)]
- pub fn foo() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- "#)
- .file("bar/build.rs", r#"
- fn main() {
- println!("cargo:rustc-cfg=bar");
- }
- "#)
- .file("bar/src/lib.rs", r#"
- #[cfg(bar)]
- pub fn bar() {}
- "#);
- assert_that(p.cargo_process("doc"),
- execs().with_status(0));
- assert_that(&p.root().join("target/doc"), existing_dir());
- assert_that(&p.root().join("target/doc/foo/fn.foo.html"), existing_file());
- assert_that(&p.root().join("target/doc/bar/fn.bar.html"), existing_file());
-}
-
-#[test]
-fn cfg_override_test() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- links = "a"
- "#)
- .file("build.rs", "")
- .file(".cargo/config", &format!(r#"
- [target.{}.a]
- rustc-cfg = ["foo"]
- "#, ::rustc_host()))
- .file("src/lib.rs", r#"
- ///
- /// ```
- /// extern crate foo;
- ///
- /// fn main() {
- /// foo::foo()
- /// }
- /// ```
- ///
- #[cfg(foo)]
- pub fn foo() {}
-
- #[cfg(foo)]
- #[test]
- fn test_foo() {
- foo()
- }
- "#)
- .file("tests/test.rs", r#"
- #[cfg(foo)]
- #[test]
- fn test_bar() {}
- "#);
- assert_that(p.cargo_process("test").arg("-v"),
- execs().with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] `[..]`
-[RUNNING] `[..]`
-[RUNNING] `[..]`
-[RUNNING] [..]foo-[..]
-[RUNNING] [..]test-[..]
-[DOCTEST] foo
-[RUNNING] [..] --cfg foo[..]", dir = p.url()))
- .with_stdout("
-running 1 test
-test test_foo ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test test_bar ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test foo_0 ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn cfg_override_doc() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- links = "a"
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file(".cargo/config", &format!(r#"
- [target.{target}.a]
- rustc-cfg = ["foo"]
- [target.{target}.b]
- rustc-cfg = ["bar"]
- "#, target = ::rustc_host()))
- .file("build.rs", "")
- .file("src/lib.rs", r#"
- #[cfg(foo)]
- pub fn foo() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- links = "b"
- "#)
- .file("bar/build.rs", "")
- .file("bar/src/lib.rs", r#"
- #[cfg(bar)]
- pub fn bar() {}
- "#) ;
- assert_that(p.cargo_process("doc"),
- execs().with_status(0));
- assert_that(&p.root().join("target/doc"), existing_dir());
- assert_that(&p.root().join("target/doc/foo/fn.foo.html"), existing_file());
- assert_that(&p.root().join("target/doc/bar/fn.bar.html"), existing_file());
-}
-
-#[test]
-fn flags_go_into_tests() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
-
- [dependencies]
- b = { path = "b" }
- "#)
- .file("src/lib.rs", "")
- .file("tests/foo.rs", "")
- .file("b/Cargo.toml", r#"
- [project]
- name = "b"
- version = "0.5.0"
- authors = []
- [dependencies]
- a = { path = "../a" }
- "#)
- .file("b/src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("a/src/lib.rs", "")
- .file("a/build.rs", r#"
- fn main() {
- println!("cargo:rustc-link-search=test");
- }
- "#);
-
- assert_that(p.cargo_process("test").arg("-v").arg("--test=foo"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] a v0.5.0 ([..]
-[RUNNING] `rustc a[..]build.rs [..]`
-[RUNNING] `[..]build-script-build[..]`
-[RUNNING] `rustc a[..]src[..]lib.rs [..] -L test[..]`
-[COMPILING] b v0.5.0 ([..]
-[RUNNING] `rustc b[..]src[..]lib.rs [..] -L test[..]`
-[COMPILING] foo v0.5.0 ([..]
-[RUNNING] `rustc src[..]lib.rs [..] -L test[..]`
-[RUNNING] `rustc tests[..]foo.rs [..] -L test[..]`
-[RUNNING] `[..]foo-[..]`")
- .with_stdout("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-
- assert_that(p.cargo("test").arg("-v").arg("-pb").arg("--lib"),
- execs().with_status(0)
- .with_stderr("\
-[FRESH] a v0.5.0 ([..]
-[COMPILING] b v0.5.0 ([..]
-[RUNNING] `rustc b[..]src[..]lib.rs [..] -L test[..]`
-[RUNNING] `[..]b-[..]`")
- .with_stdout("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn diamond_passes_args_only_once() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
-
- [dependencies]
- a = { path = "a" }
- b = { path = "b" }
- "#)
- .file("src/lib.rs", "")
- .file("tests/foo.rs", "")
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- [dependencies]
- b = { path = "../b" }
- c = { path = "../c" }
- "#)
- .file("a/src/lib.rs", "")
- .file("b/Cargo.toml", r#"
- [project]
- name = "b"
- version = "0.5.0"
- authors = []
- [dependencies]
- c = { path = "../c" }
- "#)
- .file("b/src/lib.rs", "")
- .file("c/Cargo.toml", r#"
- [project]
- name = "c"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("c/build.rs", r#"
- fn main() {
- println!("cargo:rustc-link-search=native=test");
- }
- "#)
- .file("c/src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-[COMPILING] c v0.5.0 ([..]
-[RUNNING] `rustc [..]`
-[RUNNING] `[..]`
-[RUNNING] `rustc [..]`
-[COMPILING] b v0.5.0 ([..]
-[RUNNING] `rustc [..]`
-[COMPILING] a v0.5.0 ([..]
-[RUNNING] `rustc [..]`
-[COMPILING] foo v0.5.0 ([..]
-[RUNNING] `[..]rlib -L native=test`
-"));
-}
-
-#[test]
-fn adding_an_override_invalidates() {
- let target = ::rustc_host();
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- links = "foo"
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", "")
- .file("build.rs", r#"
- fn main() {
- println!("cargo:rustc-link-search=native=foo");
- }
- "#);
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-[COMPILING] foo v0.5.0 ([..]
-[RUNNING] `rustc [..]`
-[RUNNING] `[..]`
-[RUNNING] `rustc [..] -L native=foo`
-"));
-
- File::create(p.root().join(".cargo/config")).unwrap().write_all(format!("
- [target.{}.foo]
- rustc-link-search = [\"native=bar\"]
- ", target).as_bytes()).unwrap();
-
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-[COMPILING] foo v0.5.0 ([..]
-[RUNNING] `rustc [..] -L native=bar`
-"));
-}
-
-#[test]
-fn changing_an_override_invalidates() {
- let target = ::rustc_host();
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- links = "foo"
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", &format!("
- [target.{}.foo]
- rustc-link-search = [\"native=foo\"]
- ", target))
- .file("build.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-[COMPILING] foo v0.5.0 ([..]
-[RUNNING] `rustc [..] -L native=foo`
-"));
-
- File::create(p.root().join(".cargo/config")).unwrap().write_all(format!("
- [target.{}.foo]
- rustc-link-search = [\"native=bar\"]
- ", target).as_bytes()).unwrap();
-
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-[COMPILING] foo v0.5.0 ([..]
-[RUNNING] `rustc [..] -L native=bar`
-"));
-}
-
-#[test]
-fn rebuild_only_on_explicit_paths() {
- let p = project("a")
- .file("Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() {
- println!("cargo:rerun-if-changed=foo");
- println!("cargo:rerun-if-changed=bar");
- }
- "#);
- p.build();
-
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0));
-
- // files don't exist, so should always rerun if they don't exist
- println!("run without");
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-[COMPILING] a v0.5.0 ([..])
-[RUNNING] `[..]build-script-build[..]`
-[RUNNING] `rustc src[..]lib.rs [..]`
-"));
-
- ::sleep_ms(1000);
- File::create(p.root().join("foo")).unwrap();
- File::create(p.root().join("bar")).unwrap();
-
- // now the exist, so run once, catch the mtime, then shouldn't run again
- println!("run with");
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-[COMPILING] a v0.5.0 ([..])
-[RUNNING] `[..]build-script-build[..]`
-[RUNNING] `rustc src[..]lib.rs [..]`
-"));
-
- println!("run with2");
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-[FRESH] a v0.5.0 ([..])
-"));
-
- ::sleep_ms(1000);
-
- // random other files do not affect freshness
- println!("run baz");
- File::create(p.root().join("baz")).unwrap();
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-[FRESH] a v0.5.0 ([..])
-"));
-
- // but changing dependent files does
- println!("run foo change");
- File::create(p.root().join("foo")).unwrap();
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-[COMPILING] a v0.5.0 ([..])
-[RUNNING] `[..]build-script-build[..]`
-[RUNNING] `rustc src[..]lib.rs [..]`
-"));
-
- // .. as does deleting a file
- println!("run foo delete");
- fs::remove_file(p.root().join("bar")).unwrap();
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-[COMPILING] a v0.5.0 ([..])
-[RUNNING] `[..]build-script-build[..]`
-[RUNNING] `rustc src[..]lib.rs [..]`
-"));
-}
-
-
-#[test]
-fn doctest_recieves_build_link_args() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- [dependencies.a]
- path = "a"
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- links = "bar"
- build = "build.rs"
- "#)
- .file("a/src/lib.rs", "")
- .file("a/build.rs", r#"
- fn main() {
- println!("cargo:rustc-link-search=native=bar");
- }
- "#);
-
- assert_that(p.cargo_process("test").arg("-v"),
- execs().with_status(0)
- .with_stderr_contains("\
-[RUNNING] `rustdoc --test [..] --crate-name foo [..]-L native=bar[..]`
-"));
-}
-
-#[test]
-fn please_respect_the_dag() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
-
- [dependencies]
- a = { path = 'a' }
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() {
- println!("cargo:rustc-link-search=native=foo");
- }
- "#)
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- links = "bar"
- build = "build.rs"
- "#)
- .file("a/src/lib.rs", "")
- .file("a/build.rs", r#"
- fn main() {
- println!("cargo:rustc-link-search=native=bar");
- }
- "#);
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0)
- .with_stderr_contains("\
-[RUNNING] `rustc [..] -L native=foo -L native=bar[..]`
-"));
-}
-
-#[test]
-fn non_utf8_output() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("build.rs", r#"
- use std::io::prelude::*;
-
- fn main() {
- let mut out = std::io::stdout();
- // print something that's not utf8
- out.write_all(b"\xff\xff\n").unwrap();
-
- // now print some cargo metadata that's utf8
- println!("cargo:rustc-cfg=foo");
-
- // now print more non-utf8
- out.write_all(b"\xff\xff\n").unwrap();
- }
- "#)
- .file("src/main.rs", r#"
- #[cfg(foo)]
- fn main() {}
- "#);
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn custom_target_dir() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
-
- [dependencies]
- a = { path = "a" }
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", r#"
- [build]
- target-dir = 'test'
- "#)
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("a/build.rs", "fn main() {}")
- .file("a/src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn panic_abort_with_build_scripts() {
- if !::is_nightly() {
- return
- }
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
-
- [profile.release]
- panic = 'abort'
-
- [dependencies]
- a = { path = "a" }
- "#)
- .file("src/lib.rs", "extern crate a;")
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- build = "build.rs"
-
- [build-dependencies]
- b = { path = "../b" }
- "#)
- .file("a/src/lib.rs", "")
- .file("a/build.rs", "extern crate b; fn main() {}")
- .file("b/Cargo.toml", r#"
- [project]
- name = "b"
- version = "0.5.0"
- authors = []
- "#)
- .file("b/src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v").arg("--release"),
- execs().with_status(0));
-}
+++ /dev/null
-use std::fs::{self, File};
-use std::io::prelude::*;
-use std::path::Path;
-use git2;
-
-use support::{git, project, execs, main_file, path2url};
-use support::paths::{self, CargoPathExt};
-use hamcrest::{assert_that,existing_file};
-use cargo::util::process;
-
-#[test]
-fn cargo_compile_simple_git_dep() {
- let project = project("foo");
- let git_project = git::new("dep1", |project| {
- project
- .file("Cargo.toml", r#"
- [project]
-
- name = "dep1"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
-
- [lib]
-
- name = "dep1"
- "#)
- .file("src/dep1.rs", r#"
- pub fn hello() -> &'static str {
- "hello world"
- }
- "#)
- }).unwrap();
-
- let project = project
- .file("Cargo.toml", &format!(r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.dep1]
-
- git = '{}'
-
- [[bin]]
-
- name = "foo"
- "#, git_project.url()))
- .file("src/foo.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]));
-
- let root = project.root();
- let git_root = git_project.root();
-
- assert_that(project.cargo_process("build"),
- execs()
- .with_stderr(&format!("[UPDATING] git repository `{}`\n\
- [COMPILING] dep1 v0.5.0 ({}#[..])\n\
- [COMPILING] foo v0.5.0 ({})\n",
- path2url(git_root.clone()),
- path2url(git_root),
- path2url(root))));
-
- assert_that(&project.bin("foo"), existing_file());
-
- assert_that(
- process(&project.bin("foo")),
- execs().with_stdout("hello world\n"));
-}
-
-#[test]
-fn cargo_compile_git_dep_branch() {
- let project = project("foo");
- let git_project = git::new("dep1", |project| {
- project
- .file("Cargo.toml", r#"
- [project]
-
- name = "dep1"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
-
- [lib]
-
- name = "dep1"
- "#)
- .file("src/dep1.rs", r#"
- pub fn hello() -> &'static str {
- "hello world"
- }
- "#)
- }).unwrap();
-
- // Make a new branch based on the current HEAD commit
- let repo = git2::Repository::open(&git_project.root()).unwrap();
- let head = repo.head().unwrap().target().unwrap();
- let head = repo.find_commit(head).unwrap();
- repo.branch("branchy", &head, true).unwrap();
-
- let project = project
- .file("Cargo.toml", &format!(r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.dep1]
-
- git = '{}'
- branch = "branchy"
-
- [[bin]]
-
- name = "foo"
- "#, git_project.url()))
- .file("src/foo.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]));
-
- let root = project.root();
- let git_root = git_project.root();
-
- assert_that(project.cargo_process("build"),
- execs()
- .with_stderr(&format!("[UPDATING] git repository `{}`\n\
- [COMPILING] dep1 v0.5.0 ({}?branch=branchy#[..])\n\
- [COMPILING] foo v0.5.0 ({})\n",
- path2url(git_root.clone()),
- path2url(git_root),
- path2url(root))));
-
- assert_that(&project.bin("foo"), existing_file());
-
- assert_that(
- process(&project.bin("foo")),
- execs().with_stdout("hello world\n"));
-}
-
-#[test]
-fn cargo_compile_git_dep_tag() {
- let project = project("foo");
- let git_project = git::new("dep1", |project| {
- project
- .file("Cargo.toml", r#"
- [project]
-
- name = "dep1"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
-
- [lib]
-
- name = "dep1"
- "#)
- .file("src/dep1.rs", r#"
- pub fn hello() -> &'static str {
- "hello world"
- }
- "#)
- }).unwrap();
-
- // Make a tag corresponding to the current HEAD
- let repo = git2::Repository::open(&git_project.root()).unwrap();
- let head = repo.head().unwrap().target().unwrap();
- repo.tag("v0.1.0",
- &repo.find_object(head, None).unwrap(),
- &repo.signature().unwrap(),
- "make a new tag",
- false).unwrap();
-
- let project = project
- .file("Cargo.toml", &format!(r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.dep1]
-
- git = '{}'
- tag = "v0.1.0"
-
- [[bin]]
-
- name = "foo"
- "#, git_project.url()))
- .file("src/foo.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]));
-
- let root = project.root();
- let git_root = git_project.root();
-
- assert_that(project.cargo_process("build"),
- execs()
- .with_stderr(&format!("[UPDATING] git repository `{}`\n\
- [COMPILING] dep1 v0.5.0 ({}?tag=v0.1.0#[..])\n\
- [COMPILING] foo v0.5.0 ({})\n",
- path2url(git_root.clone()),
- path2url(git_root),
- path2url(root))));
-
- assert_that(&project.bin("foo"), existing_file());
-
- assert_that(process(&project.bin("foo")),
- execs().with_stdout("hello world\n"));
-
- assert_that(project.cargo("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn cargo_compile_with_nested_paths() {
- let git_project = git::new("dep1", |project| {
- project
- .file("Cargo.toml", r#"
- [project]
-
- name = "dep1"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
-
- [dependencies.dep2]
-
- version = "0.5.0"
- path = "vendor/dep2"
-
- [lib]
-
- name = "dep1"
- "#)
- .file("src/dep1.rs", r#"
- extern crate dep2;
-
- pub fn hello() -> &'static str {
- dep2::hello()
- }
- "#)
- .file("vendor/dep2/Cargo.toml", r#"
- [project]
-
- name = "dep2"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
-
- [lib]
-
- name = "dep2"
- "#)
- .file("vendor/dep2/src/dep2.rs", r#"
- pub fn hello() -> &'static str {
- "hello world"
- }
- "#)
- }).unwrap();
-
- let p = project("parent")
- .file("Cargo.toml", &format!(r#"
- [project]
-
- name = "parent"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.dep1]
-
- version = "0.5.0"
- git = '{}'
-
- [[bin]]
-
- name = "parent"
- "#, git_project.url()))
- .file("src/parent.rs",
- &main_file(r#""{}", dep1::hello()"#, &["dep1"]));
-
- p.cargo_process("build")
- .exec_with_output()
- .unwrap();
-
- assert_that(&p.bin("parent"), existing_file());
-
- assert_that(process(&p.bin("parent")),
- execs().with_stdout("hello world\n"));
-}
-
-#[test]
-fn cargo_compile_with_meta_package() {
- let git_project = git::new("meta-dep", |project| {
- project
- .file("dep1/Cargo.toml", r#"
- [project]
-
- name = "dep1"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
-
- [lib]
-
- name = "dep1"
- "#)
- .file("dep1/src/dep1.rs", r#"
- pub fn hello() -> &'static str {
- "this is dep1"
- }
- "#)
- .file("dep2/Cargo.toml", r#"
- [project]
-
- name = "dep2"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
-
- [lib]
-
- name = "dep2"
- "#)
- .file("dep2/src/dep2.rs", r#"
- pub fn hello() -> &'static str {
- "this is dep2"
- }
- "#)
- }).unwrap();
-
- let p = project("parent")
- .file("Cargo.toml", &format!(r#"
- [project]
-
- name = "parent"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.dep1]
-
- version = "0.5.0"
- git = '{}'
-
- [dependencies.dep2]
-
- version = "0.5.0"
- git = '{}'
-
- [[bin]]
-
- name = "parent"
- "#, git_project.url(), git_project.url()))
- .file("src/parent.rs",
- &main_file(r#""{} {}", dep1::hello(), dep2::hello()"#, &["dep1", "dep2"]));
-
- p.cargo_process("build")
- .exec_with_output()
- .unwrap();
-
- assert_that(&p.bin("parent"), existing_file());
-
- assert_that(process(&p.bin("parent")),
- execs().with_stdout("this is dep1 this is dep2\n"));
-}
-
-#[test]
-fn cargo_compile_with_short_ssh_git() {
- let url = "git@github.com:a/dep";
-
- let project = project("project")
- .file("Cargo.toml", &format!(r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.dep]
-
- git = "{}"
-
- [[bin]]
-
- name = "foo"
- "#, url))
- .file("src/foo.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]));
-
- assert_that(project.cargo_process("build"),
- execs()
- .with_stdout("")
- .with_stderr(&format!("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- invalid url `{}`: relative URL without a base
-", url)));
-}
-
-#[test]
-fn two_revs_same_deps() {
- let bar = git::new("meta-dep", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.0"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
- }).unwrap();
-
- let repo = git2::Repository::open(&bar.root()).unwrap();
- let rev1 = repo.revparse_single("HEAD").unwrap().id();
-
- // Commit the changes and make sure we trigger a recompile
- File::create(&bar.root().join("src/lib.rs")).unwrap().write_all(br#"
- pub fn bar() -> i32 { 2 }
- "#).unwrap();
- git::add(&repo);
- let rev2 = git::commit(&repo);
-
- let foo = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.0.0"
- authors = []
-
- [dependencies.bar]
- git = '{}'
- rev = "{}"
-
- [dependencies.baz]
- path = "../baz"
- "#, bar.url(), rev1))
- .file("src/main.rs", r#"
- extern crate bar;
- extern crate baz;
-
- fn main() {
- assert_eq!(bar::bar(), 1);
- assert_eq!(baz::baz(), 2);
- }
- "#);
-
- let baz = project("baz")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "baz"
- version = "0.0.0"
- authors = []
-
- [dependencies.bar]
- git = '{}'
- rev = "{}"
- "#, bar.url(), rev2))
- .file("src/lib.rs", r#"
- extern crate bar;
- pub fn baz() -> i32 { bar::bar() }
- "#);
-
- baz.build();
-
- assert_that(foo.cargo_process("build").arg("-v"),
- execs().with_status(0));
- assert_that(&foo.bin("foo"), existing_file());
- assert_that(foo.process(&foo.bin("foo")), execs().with_status(0));
-}
-
-#[test]
-fn recompilation() {
- let git_project = git::new("bar", |project| {
- project
- .file("Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
-
- [lib]
- name = "bar"
- "#)
- .file("src/bar.rs", r#"
- pub fn bar() {}
- "#)
- }).unwrap();
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
-
- version = "0.5.0"
- git = '{}'
-
- [[bin]]
-
- name = "foo"
- "#, git_project.url()))
- .file("src/foo.rs",
- &main_file(r#""{:?}", bar::bar()"#, &["bar"]));
-
- // First time around we should compile both foo and bar
- assert_that(p.cargo_process("build"),
- execs().with_stderr(&format!("[UPDATING] git repository `{}`\n\
- [COMPILING] bar v0.5.0 ({}#[..])\n\
- [COMPILING] foo v0.5.0 ({})\n",
- git_project.url(),
- git_project.url(),
- p.url())));
-
- // Don't recompile the second time
- assert_that(p.cargo("build"),
- execs().with_stdout(""));
-
- // Modify a file manually, shouldn't trigger a recompile
- File::create(&git_project.root().join("src/bar.rs")).unwrap().write_all(br#"
- pub fn bar() { println!("hello!"); }
- "#).unwrap();
-
- assert_that(p.cargo("build"),
- execs().with_stdout(""));
-
- assert_that(p.cargo("update"),
- execs().with_stderr(&format!("[UPDATING] git repository `{}`",
- git_project.url())));
-
- assert_that(p.cargo("build"),
- execs().with_stdout(""));
-
- // Commit the changes and make sure we don't trigger a recompile because the
- // lockfile says not to change
- let repo = git2::Repository::open(&git_project.root()).unwrap();
- git::add(&repo);
- git::commit(&repo);
-
- println!("compile after commit");
- assert_that(p.cargo("build"),
- execs().with_stdout(""));
- p.root().move_into_the_past().unwrap();
-
- // Update the dependency and carry on!
- assert_that(p.cargo("update"),
- execs().with_stderr(&format!("[UPDATING] git repository `{}`\n\
- [UPDATING] bar v0.5.0 ([..]) -> #[..]\n\
- ",
- git_project.url())));
- println!("going for the last compile");
- assert_that(p.cargo("build"),
- execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}#[..])\n\
- [COMPILING] foo v0.5.0 ({})\n",
- git_project.url(),
- p.url())));
-
- // Make sure clean only cleans one dep
- assert_that(p.cargo("clean")
- .arg("-p").arg("foo"),
- execs().with_stdout(""));
- assert_that(p.cargo("build"),
- execs().with_stderr(&format!("[COMPILING] foo v0.5.0 ({})\n",
- p.url())));
-}
-
-#[test]
-fn update_with_shared_deps() {
- let git_project = git::new("bar", |project| {
- project
- .file("Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
-
- [lib]
- name = "bar"
- "#)
- .file("src/bar.rs", r#"
- pub fn bar() {}
- "#)
- }).unwrap();
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.dep1]
- path = "dep1"
- [dependencies.dep2]
- path = "dep2"
- "#)
- .file("src/main.rs", r#"
- extern crate dep1;
- extern crate dep2;
- fn main() {}
- "#)
- .file("dep1/Cargo.toml", &format!(r#"
- [package]
- name = "dep1"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
- version = "0.5.0"
- git = '{}'
- "#, git_project.url()))
- .file("dep1/src/lib.rs", "")
- .file("dep2/Cargo.toml", &format!(r#"
- [package]
- name = "dep2"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
- version = "0.5.0"
- git = '{}'
- "#, git_project.url()))
- .file("dep2/src/lib.rs", "");
-
- // First time around we should compile both foo and bar
- assert_that(p.cargo_process("build"),
- execs().with_stderr(&format!("\
-[UPDATING] git repository `{git}`
-[COMPILING] bar v0.5.0 ({git}#[..])
-[COMPILING] [..] v0.5.0 ([..])
-[COMPILING] [..] v0.5.0 ([..])
-[COMPILING] foo v0.5.0 ({dir})\n", git = git_project.url(), dir = p.url())));
-
- // Modify a file manually, and commit it
- File::create(&git_project.root().join("src/bar.rs")).unwrap().write_all(br#"
- pub fn bar() { println!("hello!"); }
- "#).unwrap();
- let repo = git2::Repository::open(&git_project.root()).unwrap();
- let old_head = repo.head().unwrap().target().unwrap();
- git::add(&repo);
- git::commit(&repo);
-
- ::sleep_ms(1000);
-
- // By default, not transitive updates
- println!("dep1 update");
- assert_that(p.cargo("update")
- .arg("-p").arg("dep1"),
- execs().with_stdout(""));
-
- // Don't do anything bad on a weird --precise argument
- println!("bar bad precise update");
- assert_that(p.cargo("update")
- .arg("-p").arg("bar")
- .arg("--precise").arg("0.1.2"),
- execs().with_status(101).with_stderr("\
-[UPDATING] git repository [..]
-[ERROR] Unable to update [..]
-
-To learn more, run the command again with --verbose.
-"));
-
- // Specifying a precise rev to the old rev shouldn't actually update
- // anything because we already have the rev in the db.
- println!("bar precise update");
- assert_that(p.cargo("update")
- .arg("-p").arg("bar")
- .arg("--precise").arg(&old_head.to_string()),
- execs().with_stdout(""));
-
- // Updating aggressively should, however, update the repo.
- println!("dep1 aggressive update");
- assert_that(p.cargo("update")
- .arg("-p").arg("dep1")
- .arg("--aggressive"),
- execs().with_stderr(&format!("[UPDATING] git repository `{}`\n\
- [UPDATING] bar v0.5.0 ([..]) -> #[..]\n\
- ", git_project.url())));
-
- // Make sure we still only compile one version of the git repo
- println!("build");
- assert_that(p.cargo("build"),
- execs().with_stderr(&format!("\
-[COMPILING] bar v0.5.0 ({git}#[..])
-[COMPILING] [..] v0.5.0 ({dir}[..]dep[..])
-[COMPILING] [..] v0.5.0 ({dir}[..]dep[..])
-[COMPILING] foo v0.5.0 ({dir})\n",
- git = git_project.url(), dir = p.url())));
-
- // We should be able to update transitive deps
- assert_that(p.cargo("update").arg("-p").arg("bar"),
- execs().with_stderr(&format!("[UPDATING] git repository `{}`",
- git_project.url())));
-}
-
-#[test]
-fn dep_with_submodule() {
- let project = project("foo");
- let git_project = git::new("dep1", |project| {
- project
- .file("Cargo.toml", r#"
- [package]
- name = "dep1"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
- "#)
- }).unwrap();
- let git_project2 = git::new("dep2", |project| {
- project.file("lib.rs", "pub fn dep() {}")
- }).unwrap();
-
- let repo = git2::Repository::open(&git_project.root()).unwrap();
- let url = path2url(git_project2.root()).to_string();
- git::add_submodule(&repo, &url, Path::new("src"));
- git::commit(&repo);
-
- let project = project
- .file("Cargo.toml", &format!(r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.dep1]
-
- git = '{}'
- "#, git_project.url()))
- .file("src/lib.rs", "
- extern crate dep1;
- pub fn foo() { dep1::dep() }
- ");
-
- assert_that(project.cargo_process("build"),
- execs().with_stderr("\
-[UPDATING] git repository [..]
-[COMPILING] dep1 [..]
-[COMPILING] foo [..]").with_status(0));
-}
-
-#[test]
-fn two_deps_only_update_one() {
- let project = project("foo");
- let git1 = git::new("dep1", |project| {
- project
- .file("Cargo.toml", r#"
- [package]
- name = "dep1"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
- "#)
- .file("src/lib.rs", "")
- }).unwrap();
- let git2 = git::new("dep2", |project| {
- project
- .file("Cargo.toml", r#"
- [package]
- name = "dep2"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
- "#)
- .file("src/lib.rs", "")
- }).unwrap();
-
- let project = project
- .file("Cargo.toml", &format!(r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.dep1]
- git = '{}'
- [dependencies.dep2]
- git = '{}'
- "#, git1.url(), git2.url()))
- .file("src/main.rs", "fn main() {}");
-
- assert_that(project.cargo_process("build"),
- execs()
- .with_stderr(&format!("[UPDATING] git repository `[..]`\n\
- [UPDATING] git repository `[..]`\n\
- [COMPILING] [..] v0.5.0 ([..])\n\
- [COMPILING] [..] v0.5.0 ([..])\n\
- [COMPILING] foo v0.5.0 ({})\n",
- project.url())));
-
- File::create(&git1.root().join("src/lib.rs")).unwrap().write_all(br#"
- pub fn foo() {}
- "#).unwrap();
- let repo = git2::Repository::open(&git1.root()).unwrap();
- git::add(&repo);
- git::commit(&repo);
-
- assert_that(project.cargo("update")
- .arg("-p").arg("dep1"),
- execs()
- .with_stderr(&format!("[UPDATING] git repository `{}`\n\
- [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
- ", git1.url())));
-}
-
-#[test]
-fn stale_cached_version() {
- let bar = git::new("meta-dep", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.0"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
- }).unwrap();
-
- // Update the git database in the cache with the current state of the git
- // repo
- let foo = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.0.0"
- authors = []
-
- [dependencies.bar]
- git = '{}'
- "#, bar.url()))
- .file("src/main.rs", r#"
- extern crate bar;
-
- fn main() { assert_eq!(bar::bar(), 1) }
- "#);
-
- assert_that(foo.cargo_process("build"), execs().with_status(0));
- assert_that(foo.process(&foo.bin("foo")), execs().with_status(0));
-
- // Update the repo, and simulate someone else updating the lockfile and then
- // us pulling it down.
- File::create(&bar.root().join("src/lib.rs")).unwrap().write_all(br#"
- pub fn bar() -> i32 { 1 + 0 }
- "#).unwrap();
- let repo = git2::Repository::open(&bar.root()).unwrap();
- git::add(&repo);
- git::commit(&repo);
-
- ::sleep_ms(1000);
-
- let rev = repo.revparse_single("HEAD").unwrap().id();
-
- File::create(&foo.root().join("Cargo.lock")).unwrap().write_all(format!(r#"
- [root]
- name = "foo"
- version = "0.0.0"
- dependencies = [
- 'bar 0.0.0 (git+{url}#{hash})'
- ]
-
- [[package]]
- name = "bar"
- version = "0.0.0"
- source = 'git+{url}#{hash}'
- "#, url = bar.url(), hash = rev).as_bytes()).unwrap();
-
- // Now build!
- assert_that(foo.cargo("build"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[UPDATING] git repository `{bar}`
-[COMPILING] bar v0.0.0 ({bar}#[..])
-[COMPILING] foo v0.0.0 ({foo})
-", bar = bar.url(), foo = foo.url())));
- assert_that(foo.process(&foo.bin("foo")), execs().with_status(0));
-}
-
-#[test]
-fn dep_with_changed_submodule() {
- let project = project("foo");
- let git_project = git::new("dep1", |project| {
- project
- .file("Cargo.toml", r#"
- [package]
- name = "dep1"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
- "#)
- }).unwrap();
-
- let git_project2 = git::new("dep2", |project| {
- project
- .file("lib.rs", "pub fn dep() -> &'static str { \"project2\" }")
- }).unwrap();
-
- let git_project3 = git::new("dep3", |project| {
- project
- .file("lib.rs", "pub fn dep() -> &'static str { \"project3\" }")
- }).unwrap();
-
- let repo = git2::Repository::open(&git_project.root()).unwrap();
- let mut sub = git::add_submodule(&repo, &git_project2.url().to_string(),
- &Path::new("src"));
- git::commit(&repo);
-
- let project = project
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- [dependencies.dep1]
- git = '{}'
- "#, git_project.url()))
- .file("src/main.rs", "
- extern crate dep1;
- pub fn main() { println!(\"{}\", dep1::dep()) }
- ");
-
- println!("first run");
- assert_that(project.cargo_process("run"), execs()
- .with_stderr("[UPDATING] git repository `[..]`\n\
- [COMPILING] dep1 v0.5.0 ([..])\n\
- [COMPILING] foo v0.5.0 ([..])\n\
- [RUNNING] `target[..]foo[..]`\n")
- .with_stdout("project2\n")
- .with_status(0));
-
- File::create(&git_project.root().join(".gitmodules")).unwrap()
- .write_all(format!("[submodule \"src\"]\n\tpath = src\n\turl={}",
- git_project3.url()).as_bytes()).unwrap();
-
- // Sync the submodule and reset it to the new remote.
- sub.sync().unwrap();
- {
- let subrepo = sub.open().unwrap();
- subrepo.remote_add_fetch("origin",
- "refs/heads/*:refs/heads/*").unwrap();
- subrepo.remote_set_url("origin",
- &git_project3.url().to_string()).unwrap();
- let mut origin = subrepo.find_remote("origin").unwrap();
- origin.fetch(&[], None, None).unwrap();
- let id = subrepo.refname_to_id("refs/remotes/origin/master").unwrap();
- let obj = subrepo.find_object(id, None).unwrap();
- subrepo.reset(&obj, git2::ResetType::Hard, None).unwrap();
- }
- sub.add_to_index(true).unwrap();
- git::add(&repo);
- git::commit(&repo);
-
- ::sleep_ms(1000);
- // Update the dependency and carry on!
- println!("update");
- assert_that(project.cargo("update").arg("-v"),
- execs()
- .with_stderr("")
- .with_stderr(&format!("[UPDATING] git repository `{}`\n\
- [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
- ", git_project.url())));
-
- println!("last run");
- assert_that(project.cargo("run"), execs()
- .with_stderr("[COMPILING] dep1 v0.5.0 ([..])\n\
- [COMPILING] foo v0.5.0 ([..])\n\
- [RUNNING] `target[..]foo[..]`\n")
- .with_stdout("project3\n")
- .with_status(0));
-}
-
-#[test]
-fn dev_deps_with_testing() {
- let p2 = git::new("bar", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("src/lib.rs", r#"
- pub fn gimme() -> &'static str { "zoidberg" }
- "#)
- }).unwrap();
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dev-dependencies.bar]
- version = "0.5.0"
- git = '{}'
- "#, p2.url()))
- .file("src/main.rs", r#"
- fn main() {}
-
- #[cfg(test)]
- mod tests {
- extern crate bar;
- #[test] fn foo() { bar::gimme(); }
- }
- "#);
-
- // Generate a lockfile which did not use `bar` to compile, but had to update
- // `bar` to generate the lockfile
- assert_that(p.cargo_process("build"),
- execs().with_stderr(&format!("\
-[UPDATING] git repository `{bar}`
-[COMPILING] foo v0.5.0 ({url})
-", url = p.url(), bar = p2.url())));
-
- // Make sure we use the previous resolution of `bar` instead of updating it
- // a second time.
- assert_that(p.cargo("test"),
- execs().with_stderr("\
-[COMPILING] [..] v0.5.0 ([..])
-[COMPILING] [..] v0.5.0 ([..]
-[RUNNING] target[..]foo-[..]")
- .with_stdout("
-running 1 test
-test tests::foo ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn git_build_cmd_freshness() {
- let foo = git::new("foo", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- build = "build.rs"
- "#)
- .file("build.rs", "fn main() {}")
- .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
- .file(".gitignore", "
- src/bar.rs
- ")
- }).unwrap();
- foo.root().move_into_the_past().unwrap();
-
- ::sleep_ms(1000);
-
- assert_that(foo.cargo("build"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.0 ({url})
-", url = foo.url())));
-
- // Smoke test to make sure it doesn't compile again
- println!("first pass");
- assert_that(foo.cargo("build"),
- execs().with_status(0)
- .with_stdout(""));
-
- // Modify an ignored file and make sure we don't rebuild
- println!("second pass");
- File::create(&foo.root().join("src/bar.rs")).unwrap();
- assert_that(foo.cargo("build"),
- execs().with_status(0)
- .with_stdout(""));
-}
-
-#[test]
-fn git_name_not_always_needed() {
- let p2 = git::new("bar", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("src/lib.rs", r#"
- pub fn gimme() -> &'static str { "zoidberg" }
- "#)
- }).unwrap();
-
- let repo = git2::Repository::open(&p2.root()).unwrap();
- let mut cfg = repo.config().unwrap();
- let _ = cfg.remove("user.name");
- let _ = cfg.remove("user.email");
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
-
- [dev-dependencies.bar]
- git = '{}'
- "#, p2.url()))
- .file("src/main.rs", "fn main() {}");
-
- // Generate a lockfile which did not use `bar` to compile, but had to update
- // `bar` to generate the lockfile
- assert_that(p.cargo_process("build"),
- execs().with_stderr(&format!("\
-[UPDATING] git repository `{bar}`
-[COMPILING] foo v0.5.0 ({url})
-", url = p.url(), bar = p2.url())));
-}
-
-#[test]
-fn git_repo_changing_no_rebuild() {
- let bar = git::new("bar", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
- }).unwrap();
-
- // Lock p1 to the first rev in the git repo
- let p1 = project("p1")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "p1"
- version = "0.5.0"
- authors = []
- build = 'build.rs'
- [dependencies.bar]
- git = '{}'
- "#, bar.url()))
- .file("src/main.rs", "fn main() {}")
- .file("build.rs", "fn main() {}");
- p1.build();
- p1.root().move_into_the_past().unwrap();
- assert_that(p1.cargo("build"),
- execs().with_stderr(&format!("\
-[UPDATING] git repository `{bar}`
-[COMPILING] [..]
-[COMPILING] [..]
-", bar = bar.url())));
-
- // Make a commit to lock p2 to a different rev
- File::create(&bar.root().join("src/lib.rs")).unwrap().write_all(br#"
- pub fn bar() -> i32 { 2 }
- "#).unwrap();
- let repo = git2::Repository::open(&bar.root()).unwrap();
- git::add(&repo);
- git::commit(&repo);
-
- // Lock p2 to the second rev
- let p2 = project("p2")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "p2"
- version = "0.5.0"
- authors = []
- [dependencies.bar]
- git = '{}'
- "#, bar.url()))
- .file("src/main.rs", "fn main() {}");
- assert_that(p2.cargo_process("build"),
- execs().with_stderr(&format!("\
-[UPDATING] git repository `{bar}`
-[COMPILING] [..]
-[COMPILING] [..]
-", bar = bar.url())));
-
- // And now for the real test! Make sure that p1 doesn't get rebuilt
- // even though the git repo has changed.
- assert_that(p1.cargo("build"),
- execs().with_stdout(""));
-}
-
-#[test]
-fn git_dep_build_cmd() {
- let p = git::new("foo", |project| {
- project.file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
-
- version = "0.5.0"
- path = "bar"
-
- [[bin]]
-
- name = "foo"
- "#)
- .file("src/foo.rs",
- &main_file(r#""{}", bar::gimme()"#, &["bar"]))
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- build = "build.rs"
-
- [lib]
-
- name = "bar"
- "#)
- .file("bar/src/bar.rs.in", r#"
- pub fn gimme() -> i32 { 0 }
- "#)
- .file("bar/build.rs", r#"
- use std::fs;
- fn main() {
- fs::copy("src/bar.rs.in", "src/bar.rs").unwrap();
- }
- "#)
- }).unwrap();
-
- p.root().join("bar").move_into_the_past().unwrap();
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
-
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("0\n"));
-
- // Touching bar.rs.in should cause the `build` command to run again.
- fs::File::create(&p.root().join("bar/src/bar.rs.in")).unwrap()
- .write_all(b"pub fn gimme() -> i32 { 1 }").unwrap();
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
-
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("1\n"));
-}
-
-#[test]
-fn fetch_downloads() {
- let bar = git::new("bar", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
- }).unwrap();
-
- let p = project("p1")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "p1"
- version = "0.5.0"
- authors = []
- [dependencies.bar]
- git = '{}'
- "#, bar.url()))
- .file("src/main.rs", "fn main() {}");
- assert_that(p.cargo_process("fetch"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] git repository `{url}`
-", url = bar.url())));
-
- assert_that(p.cargo("fetch"),
- execs().with_status(0).with_stdout(""));
-}
-
-#[test]
-fn warnings_in_git_dep() {
- let bar = git::new("bar", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("src/lib.rs", "fn unused() {}")
- }).unwrap();
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- [dependencies.bar]
- git = '{}'
- "#, bar.url()))
- .file("src/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("build"),
- execs()
- .with_stderr(&format!("[UPDATING] git repository `{}`\n\
- [COMPILING] bar v0.5.0 ({}#[..])\n\
- [COMPILING] foo v0.5.0 ({})\n",
- bar.url(),
- bar.url(),
- p.url())));
-}
-
-#[test]
-fn update_ambiguous() {
- let foo1 = git::new("foo1", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("src/lib.rs", "")
- }).unwrap();
- let foo2 = git::new("foo2", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.6.0"
- authors = ["wycats@example.com"]
- "#)
- .file("src/lib.rs", "")
- }).unwrap();
- let bar = git::new("bar", |project| {
- project.file("Cargo.toml", &format!(r#"
- [package]
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.foo]
- git = '{}'
- "#, foo2.url()))
- .file("src/lib.rs", "")
- }).unwrap();
-
- let p = project("project")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "project"
- version = "0.5.0"
- authors = []
- [dependencies.foo]
- git = '{}'
- [dependencies.bar]
- git = '{}'
- "#, foo1.url(), bar.url()))
- .file("src/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("generate-lockfile"), execs().with_status(0));
- assert_that(p.cargo("update")
- .arg("-p").arg("foo"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] There are multiple `foo` packages in your project, and the specification `foo` \
-is ambiguous.
-Please re-run this command with `-p <spec>` where `<spec>` is one of the \
-following:
- foo:0.[..].0
- foo:0.[..].0
-"));
-}
-
-#[test]
-fn update_one_dep_in_repo_with_many_deps() {
- let foo = git::new("foo", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("a/src/lib.rs", "")
- }).unwrap();
-
- let p = project("project")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "project"
- version = "0.5.0"
- authors = []
- [dependencies.foo]
- git = '{}'
- [dependencies.a]
- git = '{}'
- "#, foo.url(), foo.url()))
- .file("src/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("generate-lockfile"), execs().with_status(0));
- assert_that(p.cargo("update")
- .arg("-p").arg("foo"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[UPDATING] git repository `{}`
-", foo.url())));
-}
-
-#[test]
-fn switch_deps_does_not_update_transitive() {
- let transitive = git::new("transitive", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "transitive"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("src/lib.rs", "")
- }).unwrap();
- let dep1 = git::new("dep1", |project| {
- project.file("Cargo.toml", &format!(r#"
- [package]
- name = "dep"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.transitive]
- git = '{}'
- "#, transitive.url()))
- .file("src/lib.rs", "")
- }).unwrap();
- let dep2 = git::new("dep2", |project| {
- project.file("Cargo.toml", &format!(r#"
- [package]
- name = "dep"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.transitive]
- git = '{}'
- "#, transitive.url()))
- .file("src/lib.rs", "")
- }).unwrap();
-
- let p = project("project")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "project"
- version = "0.5.0"
- authors = []
- [dependencies.dep]
- git = '{}'
- "#, dep1.url()))
- .file("src/main.rs", "fn main() {}");
-
- p.build();
- assert_that(p.cargo("build"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[UPDATING] git repository `{}`
-[UPDATING] git repository `{}`
-[COMPILING] transitive [..]
-[COMPILING] dep [..]
-[COMPILING] project [..]
-", dep1.url(), transitive.url())));
-
- // Update the dependency to point to the second repository, but this
- // shouldn't update the transitive dependency which is the same.
- File::create(&p.root().join("Cargo.toml")).unwrap().write_all(format!(r#"
- [project]
- name = "project"
- version = "0.5.0"
- authors = []
- [dependencies.dep]
- git = '{}'
- "#, dep2.url()).as_bytes()).unwrap();
-
- assert_that(p.cargo("build"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[UPDATING] git repository `{}`
-[COMPILING] dep [..]
-[COMPILING] project [..]
-", dep2.url())));
-}
-
-#[test]
-fn update_one_source_updates_all_packages_in_that_git_source() {
- let dep = git::new("dep", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "dep"
- version = "0.5.0"
- authors = []
-
- [dependencies.a]
- path = "a"
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.5.0"
- authors = []
- "#)
- .file("a/src/lib.rs", "")
- }).unwrap();
-
- let p = project("project")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "project"
- version = "0.5.0"
- authors = []
- [dependencies.dep]
- git = '{}'
- "#, dep.url()))
- .file("src/main.rs", "fn main() {}");
-
- p.build();
- assert_that(p.cargo("build"),
- execs().with_status(0));
-
- let repo = git2::Repository::open(&dep.root()).unwrap();
- let rev1 = repo.revparse_single("HEAD").unwrap().id();
-
- // Just be sure to change a file
- File::create(&dep.root().join("src/lib.rs")).unwrap().write_all(br#"
- pub fn bar() -> i32 { 2 }
- "#).unwrap();
- git::add(&repo);
- git::commit(&repo);
-
- assert_that(p.cargo("update").arg("-p").arg("dep"),
- execs().with_status(0));
- let mut lockfile = String::new();
- File::open(&p.root().join("Cargo.lock")).unwrap()
- .read_to_string(&mut lockfile).unwrap();
- assert!(!lockfile.contains(&rev1.to_string()),
- "{} in {}", rev1, lockfile);
-}
-
-#[test]
-fn switch_sources() {
- let a1 = git::new("a1", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.5.0"
- authors = []
- "#)
- .file("src/lib.rs", "")
- }).unwrap();
- let a2 = git::new("a2", |project| {
- project.file("Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.5.1"
- authors = []
- "#)
- .file("src/lib.rs", "")
- }).unwrap();
-
- let p = project("project")
- .file("Cargo.toml", r#"
- [project]
- name = "project"
- version = "0.5.0"
- authors = []
- [dependencies.b]
- path = "b"
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("b/Cargo.toml", &format!(r#"
- [project]
- name = "b"
- version = "0.5.0"
- authors = []
- [dependencies.a]
- git = '{}'
- "#, a1.url()))
- .file("b/src/lib.rs", "pub fn main() {}");
-
- p.build();
- assert_that(p.cargo("build"),
- execs().with_status(0)
- .with_stderr("\
-[UPDATING] git repository `file://[..]a1`
-[COMPILING] a v0.5.0 ([..]a1#[..]
-[COMPILING] b v0.5.0 ([..])
-[COMPILING] project v0.5.0 ([..])
-"));
-
- File::create(&p.root().join("b/Cargo.toml")).unwrap().write_all(format!(r#"
- [project]
- name = "b"
- version = "0.5.0"
- authors = []
- [dependencies.a]
- git = '{}'
- "#, a2.url()).as_bytes()).unwrap();
-
- assert_that(p.cargo("build"),
- execs().with_status(0)
- .with_stderr("\
-[UPDATING] git repository `file://[..]a2`
-[COMPILING] a v0.5.1 ([..]a2#[..]
-[COMPILING] b v0.5.0 ([..])
-[COMPILING] project v0.5.0 ([..])
-"));
-}
-
-#[test]
-fn dont_require_submodules_are_checked_out() {
- let project = project("foo");
- let git1 = git::new("dep1", |p| {
- p.file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#)
- .file("build.rs", "fn main() {}")
- .file("src/lib.rs", "")
- .file("a/foo", "")
- }).unwrap();
- let git2 = git::new("dep2", |p| p).unwrap();
-
- let repo = git2::Repository::open(&git1.root()).unwrap();
- let url = path2url(git2.root()).to_string();
- git::add_submodule(&repo, &url, &Path::new("a/submodule"));
- git::commit(&repo);
-
- git2::Repository::init(&project.root()).unwrap();
- let url = path2url(git1.root()).to_string();
- let dst = paths::home().join("foo");
- git2::Repository::clone(&url, &dst).unwrap();
-
- assert_that(git1.cargo("build").arg("-v").cwd(&dst),
- execs().with_status(0));
-}
-
-#[test]
-fn doctest_same_name() {
- let a2 = git::new("a2", |p| {
- p.file("Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn a2() {}")
- }).unwrap();
-
- let a1 = git::new("a1", |p| {
- p.file("Cargo.toml", &format!(r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- [dependencies]
- a = {{ git = '{}' }}
- "#, a2.url()))
- .file("src/lib.rs", "extern crate a; pub fn a1() {}")
- }).unwrap();
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- a = {{ git = '{}' }}
- "#, a1.url()))
- .file("src/lib.rs", r#"
- #[macro_use]
- extern crate a;
- "#);
-
- assert_that(p.cargo_process("test").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn lints_are_suppressed() {
- let a = git::new("a", |p| {
- p.file("Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- "#)
- .file("src/lib.rs", "
- use std::option;
- ")
- }).unwrap();
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- a = {{ git = '{}' }}
- "#, a.url()))
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr("\
-[UPDATING] git repository `[..]`
-[COMPILING] a v0.5.0 ([..])
-[COMPILING] foo v0.0.1 ([..])
-"));
-}
-
-#[test]
-fn denied_lints_are_allowed() {
- let enabled = super::RUSTC.with(|r| r.cap_lints);
- if !enabled { return }
-
- let a = git::new("a", |p| {
- p.file("Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- "#)
- .file("src/lib.rs", "
- #![deny(warnings)]
- use std::option;
- ")
- }).unwrap();
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- a = {{ git = '{}' }}
- "#, a.url()))
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr("\
-[UPDATING] git repository `[..]`
-[COMPILING] a v0.5.0 ([..])
-[COMPILING] foo v0.0.1 ([..])
-"));
-}
-
-#[test]
-fn add_a_git_dep() {
- let git = git::new("git", |p| {
- p.file("Cargo.toml", r#"
- [project]
- name = "git"
- version = "0.5.0"
- authors = []
- "#)
- .file("src/lib.rs", "")
- }).unwrap();
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- a = {{ path = 'a' }}
- git = {{ git = '{}' }}
- "#, git.url()))
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
- "#)
- .file("a/src/lib.rs", "");
-
- assert_that(p.cargo_process("build"), execs().with_status(0));
-
- File::create(p.root().join("a/Cargo.toml")).unwrap().write_all(format!(r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- git = {{ git = '{}' }}
- "#, git.url()).as_bytes()).unwrap();
-
- assert_that(p.cargo("build"), execs().with_status(0));
-}
+++ /dev/null
-use std::fs::{self, File};
-use std::io::prelude::*;
-
-use support::{project, execs, main_file};
-use support::paths::{self, CargoPathExt};
-use hamcrest::{assert_that, existing_file};
-use cargo::util::process;
-
-#[test]
-fn cargo_compile_with_nested_deps_shorthand() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
-
- version = "0.5.0"
- path = "bar"
-
- [[bin]]
-
- name = "foo"
- "#)
- .file("src/foo.rs",
- &main_file(r#""{}", bar::gimme()"#, &["bar"]))
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.baz]
-
- version = "0.5.0"
- path = "baz"
-
- [lib]
-
- name = "bar"
- "#)
- .file("bar/src/bar.rs", r#"
- extern crate baz;
-
- pub fn gimme() -> String {
- baz::gimme()
- }
- "#)
- .file("bar/baz/Cargo.toml", r#"
- [project]
-
- name = "baz"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib]
-
- name = "baz"
- "#)
- .file("bar/baz/src/baz.rs", r#"
- pub fn gimme() -> String {
- "test passed".to_string()
- }
- "#);
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0)
- .with_stderr(&format!("[COMPILING] baz v0.5.0 ({}/bar/baz)\n\
- [COMPILING] bar v0.5.0 ({}/bar)\n\
- [COMPILING] foo v0.5.0 ({})\n",
- p.url(),
- p.url(),
- p.url())));
-
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("test passed\n").with_status(0));
-
- println!("cleaning");
- assert_that(p.cargo("clean"),
- execs().with_stdout("").with_status(0));
- println!("building baz");
- assert_that(p.cargo("build").arg("-p").arg("baz"),
- execs().with_status(0)
- .with_stderr(&format!("[COMPILING] baz v0.5.0 ({}/bar/baz)\n",
- p.url())));
- println!("building foo");
- assert_that(p.cargo("build")
- .arg("-p").arg("foo"),
- execs().with_status(0)
- .with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
- [COMPILING] foo v0.5.0 ({})\n",
- p.url(),
- p.url())));
-}
-
-#[test]
-fn cargo_compile_with_root_dev_deps() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dev-dependencies.bar]
-
- version = "0.5.0"
- path = "../bar"
-
- [[bin]]
- name = "foo"
- "#)
- .file("src/main.rs",
- &main_file(r#""{}", bar::gimme()"#, &["bar"]));
- let p2 = project("bar")
- .file("Cargo.toml", r#"
- [package]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("src/lib.rs", r#"
- pub fn gimme() -> &'static str {
- "zoidberg"
- }
- "#);
-
- p2.build();
- assert_that(p.cargo_process("build"),
- execs().with_status(101))
-}
-
-#[test]
-fn cargo_compile_with_root_dev_deps_with_testing() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dev-dependencies.bar]
-
- version = "0.5.0"
- path = "../bar"
-
- [[bin]]
- name = "foo"
- "#)
- .file("src/main.rs",
- &main_file(r#""{}", bar::gimme()"#, &["bar"]));
- let p2 = project("bar")
- .file("Cargo.toml", r#"
- [package]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("src/lib.rs", r#"
- pub fn gimme() -> &'static str {
- "zoidberg"
- }
- "#);
-
- p2.build();
- assert_that(p.cargo_process("test"),
- execs().with_stderr("\
-[COMPILING] [..] v0.5.0 ([..])
-[COMPILING] [..] v0.5.0 ([..])
-[RUNNING] target[..]foo-[..]")
- .with_stdout("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn cargo_compile_with_transitive_dev_deps() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
-
- version = "0.5.0"
- path = "bar"
-
- [[bin]]
-
- name = "foo"
- "#)
- .file("src/foo.rs",
- &main_file(r#""{}", bar::gimme()"#, &["bar"]))
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dev-dependencies.baz]
-
- git = "git://example.com/path/to/nowhere"
-
- [lib]
-
- name = "bar"
- "#)
- .file("bar/src/bar.rs", r#"
- pub fn gimme() -> &'static str {
- "zoidberg"
- }
- "#);
-
- assert_that(p.cargo_process("build"),
- execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
- [COMPILING] foo v0.5.0 ({})\n",
- p.url(),
- p.url())));
-
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("zoidberg\n"));
-}
-
-#[test]
-fn no_rebuild_dependency() {
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [[bin]] name = "foo"
- [dependencies.bar] path = "bar"
- "#)
- .file("src/foo.rs", r#"
- extern crate bar;
- fn main() { bar::bar() }
- "#)
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib] name = "bar"
- "#)
- .file("bar/src/bar.rs", r#"
- pub fn bar() {}
- "#);
- // First time around we should compile both foo and bar
- assert_that(p.cargo_process("build"),
- execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
- [COMPILING] foo v0.5.0 ({})\n",
- p.url(),
- p.url())));
- // This time we shouldn't compile bar
- assert_that(p.cargo("build"),
- execs().with_stdout(""));
- p.root().move_into_the_past().unwrap();
-
- p.build(); // rebuild the files (rewriting them in the process)
- assert_that(p.cargo("build"),
- execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
- [COMPILING] foo v0.5.0 ({})\n",
- p.url(),
- p.url())));
-}
-
-#[test]
-fn deep_dependencies_trigger_rebuild() {
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [[bin]]
- name = "foo"
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/foo.rs", r#"
- extern crate bar;
- fn main() { bar::bar() }
- "#)
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib]
- name = "bar"
- [dependencies.baz]
- path = "../baz"
- "#)
- .file("bar/src/bar.rs", r#"
- extern crate baz;
- pub fn bar() { baz::baz() }
- "#)
- .file("baz/Cargo.toml", r#"
- [project]
-
- name = "baz"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib]
- name = "baz"
- "#)
- .file("baz/src/baz.rs", r#"
- pub fn baz() {}
- "#);
- assert_that(p.cargo_process("build"),
- execs().with_stderr(&format!("[COMPILING] baz v0.5.0 ({}/baz)\n\
- [COMPILING] bar v0.5.0 ({}/bar)\n\
- [COMPILING] foo v0.5.0 ({})\n",
- p.url(),
- p.url(),
- p.url())));
- assert_that(p.cargo("build"),
- execs().with_stdout(""));
-
- // Make sure an update to baz triggers a rebuild of bar
- //
- // We base recompilation off mtime, so sleep for at least a second to ensure
- // that this write will change the mtime.
- ::sleep_ms(1000);
- File::create(&p.root().join("baz/src/baz.rs")).unwrap().write_all(br#"
- pub fn baz() { println!("hello!"); }
- "#).unwrap();
- assert_that(p.cargo("build"),
- execs().with_stderr(&format!("[COMPILING] baz v0.5.0 ({}/baz)\n\
- [COMPILING] bar v0.5.0 ({}/bar)\n\
- [COMPILING] foo v0.5.0 ({})\n",
- p.url(),
- p.url(),
- p.url())));
-
- // Make sure an update to bar doesn't trigger baz
- ::sleep_ms(1000);
- File::create(&p.root().join("bar/src/bar.rs")).unwrap().write_all(br#"
- extern crate baz;
- pub fn bar() { println!("hello!"); baz::baz(); }
- "#).unwrap();
- assert_that(p.cargo("build"),
- execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
- [COMPILING] foo v0.5.0 ({})\n",
- p.url(),
- p.url())));
-
-}
-
-#[test]
-fn no_rebuild_two_deps() {
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [[bin]]
- name = "foo"
- [dependencies.bar]
- path = "bar"
- [dependencies.baz]
- path = "baz"
- "#)
- .file("src/foo.rs", r#"
- extern crate bar;
- fn main() { bar::bar() }
- "#)
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib]
- name = "bar"
- [dependencies.baz]
- path = "../baz"
- "#)
- .file("bar/src/bar.rs", r#"
- pub fn bar() {}
- "#)
- .file("baz/Cargo.toml", r#"
- [project]
-
- name = "baz"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib]
- name = "baz"
- "#)
- .file("baz/src/baz.rs", r#"
- pub fn baz() {}
- "#);
- assert_that(p.cargo_process("build"),
- execs().with_stderr(&format!("[COMPILING] baz v0.5.0 ({}/baz)\n\
- [COMPILING] bar v0.5.0 ({}/bar)\n\
- [COMPILING] foo v0.5.0 ({})\n",
- p.url(),
- p.url(),
- p.url())));
- assert_that(&p.bin("foo"), existing_file());
- assert_that(p.cargo("build"),
- execs().with_stdout(""));
- assert_that(&p.bin("foo"), existing_file());
-}
-
-#[test]
-fn nested_deps_recompile() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
-
- version = "0.5.0"
- path = "src/bar"
-
- [[bin]]
-
- name = "foo"
- "#)
- .file("src/foo.rs",
- &main_file(r#""{}", bar::gimme()"#, &["bar"]))
- .file("src/bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [lib]
-
- name = "bar"
- "#)
- .file("src/bar/src/bar.rs", "pub fn gimme() -> i32 { 92 }");
- let bar = p.url();
-
- assert_that(p.cargo_process("build"),
- execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/src/bar)\n\
- [COMPILING] foo v0.5.0 ({})\n",
- bar,
- p.url())));
- ::sleep_ms(1000);
-
- File::create(&p.root().join("src/foo.rs")).unwrap().write_all(br#"
- fn main() {}
- "#).unwrap();
-
- // This shouldn't recompile `bar`
- assert_that(p.cargo("build"),
- execs().with_stderr(&format!("[COMPILING] foo v0.5.0 ({})\n",
- p.url())));
-}
-
-#[test]
-fn error_message_for_missing_manifest() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
-
- path = "src/bar"
-
- [lib]
-
- name = "foo"
- "#)
- .file("src/bar/not-a-manifest", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] Unable to update file://[..]
-
-Caused by:
- failed to read `[..]bar[..]Cargo.toml`
-
-Caused by:
- [..] (os error [..])
-"));
-
-}
-
-#[test]
-fn override_relative() {
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("src/lib.rs", "");
-
- fs::create_dir(&paths::root().join(".cargo")).unwrap();
- File::create(&paths::root().join(".cargo/config")).unwrap()
- .write_all(br#"paths = ["bar"]"#).unwrap();
-
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [package]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
- path = '{}'
- "#, bar.root().display()))
- .file("src/lib.rs", "");
- bar.build();
- assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0));
-
-}
-
-#[test]
-fn override_self() {
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("src/lib.rs", "");
-
- let p = project("foo");
- let root = p.root().clone();
- let p = p
- .file(".cargo/config", &format!(r#"
- paths = ['{}']
- "#, root.display()))
- .file("Cargo.toml", &format!(r#"
- [package]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
- path = '{}'
-
- "#, bar.root().display()))
- .file("src/lib.rs", "")
- .file("src/main.rs", "fn main() {}");
-
- bar.build();
- assert_that(p.cargo_process("build"), execs().with_status(0));
-
-}
-
-#[test]
-fn override_path_dep() {
- let bar = project("bar")
- .file("p1/Cargo.toml", r#"
- [package]
- name = "p1"
- version = "0.5.0"
- authors = []
-
- [dependencies.p2]
- path = "../p2"
- "#)
- .file("p1/src/lib.rs", "")
- .file("p2/Cargo.toml", r#"
- [package]
- name = "p2"
- version = "0.5.0"
- authors = []
- "#)
- .file("p2/src/lib.rs", "");
-
- let p = project("foo")
- .file(".cargo/config", &format!(r#"
- paths = ['{}', '{}']
- "#, bar.root().join("p1").display(),
- bar.root().join("p2").display()))
- .file("Cargo.toml", &format!(r#"
- [package]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.p2]
- path = '{}'
-
- "#, bar.root().join("p2").display()))
- .file("src/lib.rs", "");
-
- bar.build();
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
-
-}
-
-#[test]
-fn path_dep_build_cmd() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
-
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
-
- version = "0.5.0"
- path = "bar"
-
- [[bin]]
-
- name = "foo"
- "#)
- .file("src/foo.rs",
- &main_file(r#""{}", bar::gimme()"#, &["bar"]))
- .file("bar/Cargo.toml", r#"
- [project]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- build = "build.rs"
-
- [lib]
-
- name = "bar"
- "#)
- .file("bar/build.rs", r#"
- use std::fs;
- fn main() {
- fs::copy("src/bar.rs.in", "src/bar.rs").unwrap();
- }
- "#)
- .file("bar/src/bar.rs.in", r#"
- pub fn gimme() -> i32 { 0 }
- "#);
-
- p.build();
- p.root().join("bar").move_into_the_past().unwrap();
-
- assert_that(p.cargo("build"),
- execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
- [COMPILING] foo v0.5.0 ({})\n",
- p.url(),
- p.url())));
-
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("0\n"));
-
- // Touching bar.rs.in should cause the `build` command to run again.
- {
- let file = fs::File::create(&p.root().join("bar/src/bar.rs.in"));
- file.unwrap().write_all(br#"pub fn gimme() -> i32 { 1 }"#).unwrap();
- }
-
- assert_that(p.cargo("build"),
- execs().with_stderr(&format!("[COMPILING] bar v0.5.0 ({}/bar)\n\
- [COMPILING] foo v0.5.0 ({})\n",
- p.url(),
- p.url())));
-
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("1\n"));
-}
-
-#[test]
-fn dev_deps_no_rebuild_lib() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
-
- [dev-dependencies.bar]
- path = "bar"
-
- [lib]
- name = "foo"
- doctest = false
- "#)
- .file("src/lib.rs", r#"
- #[cfg(test)] extern crate bar;
- #[cfg(not(test))] pub fn foo() { env!("FOO"); }
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
-
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- "#)
- .file("bar/src/lib.rs", "pub fn bar() {}");
- p.build();
- assert_that(p.cargo("build")
- .env("FOO", "bar"),
- execs().with_status(0)
- .with_stderr(&format!("[COMPILING] foo v0.5.0 ({})\n",
- p.url())));
-
- assert_that(p.cargo("test"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] [..] v0.5.0 ({url}[..])
-[COMPILING] [..] v0.5.0 ({url}[..])
-[RUNNING] target[..]foo-[..]", url = p.url()))
- .with_stdout("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn custom_target_no_rebuild() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- [dependencies]
- a = { path = "a" }
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- "#)
- .file("a/src/lib.rs", "")
- .file("b/Cargo.toml", r#"
- [project]
- name = "b"
- version = "0.5.0"
- authors = []
- [dependencies]
- a = { path = "../a" }
- "#)
- .file("b/src/lib.rs", "");
- p.build();
- assert_that(p.cargo("build"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] a v0.5.0 ([..])
-[COMPILING] foo v0.5.0 ([..])
-"));
-
- assert_that(p.cargo("build")
- .arg("--manifest-path=b/Cargo.toml")
- .env("CARGO_TARGET_DIR", "target"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] b v0.5.0 ([..])
-"));
-}
-
-#[test]
-fn override_and_depend() {
- let p = project("foo")
- .file("a/a1/Cargo.toml", r#"
- [project]
- name = "a1"
- version = "0.5.0"
- authors = []
- [dependencies]
- a2 = { path = "../a2" }
- "#)
- .file("a/a1/src/lib.rs", "")
- .file("a/a2/Cargo.toml", r#"
- [project]
- name = "a2"
- version = "0.5.0"
- authors = []
- "#)
- .file("a/a2/src/lib.rs", "")
- .file("b/Cargo.toml", r#"
- [project]
- name = "b"
- version = "0.5.0"
- authors = []
- [dependencies]
- a1 = { path = "../a/a1" }
- a2 = { path = "../a/a2" }
- "#)
- .file("b/src/lib.rs", "")
- .file("b/.cargo/config", r#"
- paths = ["../a"]
- "#);
- p.build();
- assert_that(p.cargo("build").cwd(p.root().join("b")),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] a2 v0.5.0 ([..])
-[COMPILING] a1 v0.5.0 ([..])
-[COMPILING] b v0.5.0 ([..])
-"));
-}
-
-#[test]
-fn missing_path_dependency() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", r#"
- paths = ["../whoa-this-does-not-exist"]
- "#);
- p.build();
- assert_that(p.cargo("build"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] failed to update path override `[..]../whoa-this-does-not-exist` \
-(defined in `[..]`)
-
-Caused by:
- failed to read directory `[..]`
-
-Caused by:
- [..] (os error [..])
-"));
-}
+++ /dev/null
-use std::fs;
-use std::env;
-
-use support::{project, execs};
-use hamcrest::assert_that;
-
-#[test]
-fn plugin_to_the_max() {
- if !::is_nightly() { return }
-
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo_lib"
-
- [dependencies.bar]
- path = "../bar"
- "#)
- .file("src/main.rs", r#"
- #![feature(plugin)]
- #![plugin(bar)]
- extern crate foo_lib;
-
- fn main() { foo_lib::foo(); }
- "#)
- .file("src/foo_lib.rs", r#"
- #![feature(plugin)]
- #![plugin(bar)]
-
- pub fn foo() {}
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "bar"
- plugin = true
-
- [dependencies.baz]
- path = "../baz"
- "#)
- .file("src/lib.rs", r#"
- #![feature(plugin_registrar, rustc_private)]
-
- extern crate rustc_plugin;
- extern crate baz;
-
- use rustc_plugin::Registry;
-
- #[plugin_registrar]
- pub fn foo(_reg: &mut Registry) {
- println!("{}", baz::baz());
- }
- "#);
- let baz = project("baz")
- .file("Cargo.toml", r#"
- [package]
- name = "baz"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "baz"
- crate_type = ["dylib"]
- "#)
- .file("src/lib.rs", "pub fn baz() -> i32 { 1 }");
- bar.build();
- baz.build();
-
- assert_that(foo.cargo_process("build"),
- execs().with_status(0));
- assert_that(foo.cargo("doc"),
- execs().with_status(0));
-}
-
-#[test]
-fn plugin_with_dynamic_native_dependency() {
- if !::is_nightly() { return }
-
- let build = project("builder")
- .file("Cargo.toml", r#"
- [package]
- name = "builder"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "builder"
- crate-type = ["dylib"]
- "#)
- .file("src/lib.rs", r#"
- #[no_mangle]
- pub extern fn foo() {}
- "#);
- assert_that(build.cargo_process("build"),
- execs().with_status(0));
- let src = build.root().join("target/debug");
- let lib = fs::read_dir(&src).unwrap().map(|s| s.unwrap().path()).find(|lib| {
- let lib = lib.file_name().unwrap().to_str().unwrap();
- lib.starts_with(env::consts::DLL_PREFIX) &&
- lib.ends_with(env::consts::DLL_SUFFIX)
- }).unwrap();
-
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/main.rs", r#"
- #![feature(plugin)]
- #![plugin(bar)]
-
- fn main() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- build = 'build.rs'
-
- [lib]
- name = "bar"
- plugin = true
- "#)
- .file("bar/build.rs", r#"
- use std::path::PathBuf;
- use std::env;
-
- fn main() {
- let src = PathBuf::from(env::var("SRC").unwrap());
- println!("cargo:rustc-flags=-L {}", src.parent().unwrap()
- .display());
- }
- "#)
- .file("bar/src/lib.rs", r#"
- #![feature(plugin_registrar, rustc_private)]
- extern crate rustc_plugin;
-
- use rustc_plugin::Registry;
-
- #[cfg_attr(not(target_env = "msvc"), link(name = "builder"))]
- #[cfg_attr(target_env = "msvc", link(name = "builder.dll"))]
- extern { fn foo(); }
-
- #[plugin_registrar]
- pub fn bar(_reg: &mut Registry) {
- unsafe { foo() }
- }
- "#);
-
- assert_that(foo.cargo_process("build").env("SRC", &lib).arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn plugin_integration() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
-
- [lib]
- name = "foo"
- plugin = true
- doctest = false
- "#)
- .file("build.rs", "fn main() {}")
- .file("src/lib.rs", "")
- .file("tests/it_works.rs", "");
-
- assert_that(p.cargo_process("test").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn doctest_a_plugin() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = { path = "bar" }
- "#)
- .file("src/lib.rs", r#"
- #[macro_use]
- extern crate bar;
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "bar"
- plugin = true
- "#)
- .file("bar/src/lib.rs", r#"
- pub fn bar() {}
- "#);
-
- assert_that(p.cargo_process("test").arg("-v"),
- execs().with_status(0));
-}
-
-// See #1515
-#[test]
-fn native_plugin_dependency_with_custom_ar_linker() {
- let target = ::rustc_host();
-
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo"
- plugin = true
- "#)
- .file("src/lib.rs", "");
-
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "bar"
-
- [dependencies.foo]
- path = "../foo"
- "#)
- .file("src/lib", "")
- .file(".cargo/config", &format!(r#"
- [target.{}]
- ar = "nonexistent-ar"
- linker = "nonexistent-linker"
- "#, target));
-
- foo.build();
- assert_that(bar.cargo_process("build").arg("--verbose"),
- execs().with_stderr_contains("\
-[COMPILING] foo v0.0.1 ([..])
-[RUNNING] `rustc [..] -C ar=nonexistent-ar -C linker=nonexistent-linker [..]`
-[ERROR] could not exec the linker [..]
-"));
-}
+++ /dev/null
-use std::io::Write;
-use std::fs::{self, File};
-use support::{project, execs, paths};
-use hamcrest::assert_that;
-
-#[test]
-fn env_rustflags_normal_source() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", "")
- .file("src/bin/a.rs", "fn main() {}")
- .file("examples/b.rs", "fn main() {}")
- .file("tests/c.rs", "#[test] fn f() { }")
- .file("benches/d.rs", r#"
- #![feature(test)]
- extern crate test;
- #[bench] fn run1(_ben: &mut test::Bencher) { }"#);
- p.build();
-
- // Use RUSTFLAGS to pass an argument that will generate an error
- assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
- .arg("--lib"),
- execs().with_status(101));
- assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
- .arg("--bin=a"),
- execs().with_status(101));
- assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
- .arg("--example=b"),
- execs().with_status(101));
- assert_that(p.cargo("test").env("RUSTFLAGS", "-Z bogus"),
- execs().with_status(101));
- assert_that(p.cargo("bench").env("RUSTFLAGS", "-Z bogus"),
- execs().with_status(101));
-}
-
-#[test]
-fn env_rustflags_build_script() {
- // RUSTFLAGS should be passed to rustc for build scripts
- // when --target is not specified.
- // In this test if --cfg foo is passed the build will fail.
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() { }
- #[cfg(not(foo))]
- fn main() { }
- "#);
- p.build();
-
- assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
- execs().with_status(0));
-}
-
-#[test]
-fn env_rustflags_build_script_dep() {
- // RUSTFLAGS should be passed to rustc for build scripts
- // when --target is not specified.
- // In this test if --cfg foo is not passed the build will fail.
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- build = "build.rs"
-
- [build-dependencies.bar]
- path = "../bar"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() { }
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", r#"
- fn bar() { }
- #[cfg(not(foo))]
- fn bar() { }
- "#);
- foo.build();
- bar.build();
-
- assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo"),
- execs().with_status(0));
-}
-
-#[test]
-fn env_rustflags_plugin() {
- // RUSTFLAGS should be passed to rustc for plugins
- // when --target is not specified.
- // In this test if --cfg foo is not passed the build will fail.
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
-
- [lib]
- name = "foo"
- plugin = true
- "#)
- .file("src/lib.rs", r#"
- fn main() { }
- #[cfg(not(foo))]
- fn main() { }
- "#);
- p.build();
-
- assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
- execs().with_status(0));
-}
-
-#[test]
-fn env_rustflags_plugin_dep() {
- // RUSTFLAGS should be passed to rustc for plugins
- // when --target is not specified.
- // In this test if --cfg foo is not passed the build will fail.
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
-
- [lib]
- name = "foo"
- plugin = true
-
- [dependencies.bar]
- path = "../bar"
- "#)
- .file("src/lib.rs", r#"
- fn foo() { }
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
-
- [lib]
- name = "bar"
- "#)
- .file("src/lib.rs", r#"
- fn bar() { }
- #[cfg(not(foo))]
- fn bar() { }
- "#);
- foo.build();
- bar.build();
-
- assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo"),
- execs().with_status(0));
-}
-
-#[test]
-fn env_rustflags_normal_source_with_target() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", "")
- .file("src/bin/a.rs", "fn main() {}")
- .file("examples/b.rs", "fn main() {}")
- .file("tests/c.rs", "#[test] fn f() { }")
- .file("benches/d.rs", r#"
- #![feature(test)]
- extern crate test;
- #[bench] fn run1(_ben: &mut test::Bencher) { }"#);
- p.build();
-
- let ref host = ::rustc_host();
-
- // Use RUSTFLAGS to pass an argument that will generate an error
- assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
- .arg("--lib").arg("--target").arg(host),
- execs().with_status(101));
- assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
- .arg("--bin=a").arg("--target").arg(host),
- execs().with_status(101));
- assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
- .arg("--example=b").arg("--target").arg(host),
- execs().with_status(101));
- assert_that(p.cargo("test").env("RUSTFLAGS", "-Z bogus")
- .arg("--target").arg(host),
- execs().with_status(101));
- assert_that(p.cargo("bench").env("RUSTFLAGS", "-Z bogus")
- .arg("--target").arg(host),
- execs().with_status(101));
-}
-
-#[test]
-fn env_rustflags_build_script_with_target() {
- // RUSTFLAGS should not be passed to rustc for build scripts
- // when --target is specified.
- // In this test if --cfg foo is passed the build will fail.
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() { }
- #[cfg(foo)]
- fn main() { }
- "#);
- p.build();
-
- let host = ::rustc_host();
- assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo")
- .arg("--target").arg(host),
- execs().with_status(0));
-}
-
-#[test]
-fn env_rustflags_build_script_dep_with_target() {
- // RUSTFLAGS should not be passed to rustc for build scripts
- // when --target is specified.
- // In this test if --cfg foo is passed the build will fail.
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- build = "build.rs"
-
- [build-dependencies.bar]
- path = "../bar"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() { }
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", r#"
- fn bar() { }
- #[cfg(foo)]
- fn bar() { }
- "#);
- foo.build();
- bar.build();
-
- let host = ::rustc_host();
- assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo")
- .arg("--target").arg(host),
- execs().with_status(0));
-}
-
-#[test]
-fn env_rustflags_plugin_with_target() {
- // RUSTFLAGS should not be passed to rustc for plugins
- // when --target is specified.
- // In this test if --cfg foo is passed the build will fail.
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
-
- [lib]
- name = "foo"
- plugin = true
- "#)
- .file("src/lib.rs", r#"
- fn main() { }
- #[cfg(foo)]
- fn main() { }
- "#);
- p.build();
-
- let host = ::rustc_host();
- assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo")
- .arg("--target").arg(host),
- execs().with_status(0));
-}
-
-#[test]
-fn env_rustflags_plugin_dep_with_target() {
- // RUSTFLAGS should not be passed to rustc for plugins
- // when --target is specified.
- // In this test if --cfg foo is passed the build will fail.
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
-
- [lib]
- name = "foo"
- plugin = true
-
- [dependencies.bar]
- path = "../bar"
- "#)
- .file("src/lib.rs", r#"
- fn foo() { }
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
-
- [lib]
- name = "bar"
- "#)
- .file("src/lib.rs", r#"
- fn bar() { }
- #[cfg(foo)]
- fn bar() { }
- "#);
- foo.build();
- bar.build();
-
- let host = ::rustc_host();
- assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo")
- .arg("--target").arg(host),
- execs().with_status(0));
-}
-
-#[test]
-fn env_rustflags_recompile() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", "");
- p.build();
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
- // Setting RUSTFLAGS forces a recompile
- assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus"),
- execs().with_status(101));
-}
-
-#[test]
-fn env_rustflags_recompile2() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", "");
- p.build();
-
- assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
- execs().with_status(0));
- // Setting RUSTFLAGS forces a recompile
- assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus"),
- execs().with_status(101));
-}
-
-#[test]
-fn env_rustflags_no_recompile() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", "");
- p.build();
-
- assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
- execs().with_status(0));
- assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
- execs().with_stdout("").with_status(0));
-}
-
-#[test]
-fn build_rustflags_normal_source() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", "")
- .file("src/bin/a.rs", "fn main() {}")
- .file("examples/b.rs", "fn main() {}")
- .file("tests/c.rs", "#[test] fn f() { }")
- .file("benches/d.rs", r#"
- #![feature(test)]
- extern crate test;
- #[bench] fn run1(_ben: &mut test::Bencher) { }"#)
- .file(".cargo/config", r#"
- [build]
- rustflags = ["-Z", "bogus"]
- "#);
- p.build();
-
- assert_that(p.cargo("build")
- .arg("--lib"),
- execs().with_status(101));
- assert_that(p.cargo("build")
- .arg("--bin=a"),
- execs().with_status(101));
- assert_that(p.cargo("build")
- .arg("--example=b"),
- execs().with_status(101));
- assert_that(p.cargo("test"),
- execs().with_status(101));
- assert_that(p.cargo("bench"),
- execs().with_status(101));
-}
-
-#[test]
-fn build_rustflags_build_script() {
- // RUSTFLAGS should be passed to rustc for build scripts
- // when --target is not specified.
- // In this test if --cfg foo is passed the build will fail.
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() { }
- #[cfg(not(foo))]
- fn main() { }
- "#)
- .file(".cargo/config", r#"
- [build]
- rustflags = ["--cfg", "foo"]
- "#);
- p.build();
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn build_rustflags_build_script_dep() {
- // RUSTFLAGS should be passed to rustc for build scripts
- // when --target is not specified.
- // In this test if --cfg foo is not passed the build will fail.
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- build = "build.rs"
-
- [build-dependencies.bar]
- path = "../bar"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() { }
- "#)
- .file(".cargo/config", r#"
- [build]
- rustflags = ["--cfg", "foo"]
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", r#"
- fn bar() { }
- #[cfg(not(foo))]
- fn bar() { }
- "#);
- foo.build();
- bar.build();
-
- assert_that(foo.cargo("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn build_rustflags_plugin() {
- // RUSTFLAGS should be passed to rustc for plugins
- // when --target is not specified.
- // In this test if --cfg foo is not passed the build will fail.
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
-
- [lib]
- name = "foo"
- plugin = true
- "#)
- .file("src/lib.rs", r#"
- fn main() { }
- #[cfg(not(foo))]
- fn main() { }
- "#)
- .file(".cargo/config", r#"
- [build]
- rustflags = ["--cfg", "foo"]
- "#);
- p.build();
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn build_rustflags_plugin_dep() {
- // RUSTFLAGS should be passed to rustc for plugins
- // when --target is not specified.
- // In this test if --cfg foo is not passed the build will fail.
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
-
- [lib]
- name = "foo"
- plugin = true
-
- [dependencies.bar]
- path = "../bar"
- "#)
- .file("src/lib.rs", r#"
- fn foo() { }
- "#)
- .file(".cargo/config", r#"
- [build]
- rustflags = ["--cfg", "foo"]
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
-
- [lib]
- name = "bar"
- "#)
- .file("src/lib.rs", r#"
- fn bar() { }
- #[cfg(not(foo))]
- fn bar() { }
- "#);
- foo.build();
- bar.build();
-
- assert_that(foo.cargo("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn build_rustflags_normal_source_with_target() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", "")
- .file("src/bin/a.rs", "fn main() {}")
- .file("examples/b.rs", "fn main() {}")
- .file("tests/c.rs", "#[test] fn f() { }")
- .file("benches/d.rs", r#"
- #![feature(test)]
- extern crate test;
- #[bench] fn run1(_ben: &mut test::Bencher) { }"#)
- .file(".cargo/config", r#"
- [build]
- rustflags = ["-Z", "bogus"]
- "#);
- p.build();
-
- let ref host = ::rustc_host();
-
- // Use RUSTFLAGS to pass an argument that will generate an error
- assert_that(p.cargo("build")
- .arg("--lib").arg("--target").arg(host),
- execs().with_status(101));
- assert_that(p.cargo("build")
- .arg("--bin=a").arg("--target").arg(host),
- execs().with_status(101));
- assert_that(p.cargo("build")
- .arg("--example=b").arg("--target").arg(host),
- execs().with_status(101));
- assert_that(p.cargo("test")
- .arg("--target").arg(host),
- execs().with_status(101));
- assert_that(p.cargo("bench")
- .arg("--target").arg(host),
- execs().with_status(101));
-}
-
-#[test]
-fn build_rustflags_build_script_with_target() {
- // RUSTFLAGS should not be passed to rustc for build scripts
- // when --target is specified.
- // In this test if --cfg foo is passed the build will fail.
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() { }
- #[cfg(foo)]
- fn main() { }
- "#)
- .file(".cargo/config", r#"
- [build]
- rustflags = ["--cfg", "foo"]
- "#);
- p.build();
-
- let host = ::rustc_host();
- assert_that(p.cargo("build")
- .arg("--target").arg(host),
- execs().with_status(0));
-}
-
-#[test]
-fn build_rustflags_build_script_dep_with_target() {
- // RUSTFLAGS should not be passed to rustc for build scripts
- // when --target is specified.
- // In this test if --cfg foo is passed the build will fail.
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- build = "build.rs"
-
- [build-dependencies.bar]
- path = "../bar"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- fn main() { }
- "#)
- .file(".cargo/config", r#"
- [build]
- rustflags = ["--cfg", "foo"]
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", r#"
- fn bar() { }
- #[cfg(foo)]
- fn bar() { }
- "#);
- foo.build();
- bar.build();
-
- let host = ::rustc_host();
- assert_that(foo.cargo("build")
- .arg("--target").arg(host),
- execs().with_status(0));
-}
-
-#[test]
-fn build_rustflags_plugin_with_target() {
- // RUSTFLAGS should not be passed to rustc for plugins
- // when --target is specified.
- // In this test if --cfg foo is passed the build will fail.
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
-
- [lib]
- name = "foo"
- plugin = true
- "#)
- .file("src/lib.rs", r#"
- fn main() { }
- #[cfg(foo)]
- fn main() { }
- "#)
- .file(".cargo/config", r#"
- [build]
- rustflags = ["--cfg", "foo"]
- "#);
- p.build();
-
- let host = ::rustc_host();
- assert_that(p.cargo("build")
- .arg("--target").arg(host),
- execs().with_status(0));
-}
-
-#[test]
-fn build_rustflags_plugin_dep_with_target() {
- // RUSTFLAGS should not be passed to rustc for plugins
- // when --target is specified.
- // In this test if --cfg foo is passed the build will fail.
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
-
- [lib]
- name = "foo"
- plugin = true
-
- [dependencies.bar]
- path = "../bar"
- "#)
- .file("src/lib.rs", r#"
- fn foo() { }
- "#)
- .file(".cargo/config", r#"
- [build]
- rustflags = ["--cfg", "foo"]
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
-
- [lib]
- name = "bar"
- "#)
- .file("src/lib.rs", r#"
- fn bar() { }
- #[cfg(foo)]
- fn bar() { }
- "#);
- foo.build();
- bar.build();
-
- let host = ::rustc_host();
- assert_that(foo.cargo("build")
- .arg("--target").arg(host),
- execs().with_status(0));
-}
-
-#[test]
-fn build_rustflags_recompile() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", "");
- p.build();
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
-
- // Setting RUSTFLAGS forces a recompile
- let config = r#"
- [build]
- rustflags = ["-Z", "bogus"]
- "#;
- let config_file = paths::root().join("foo/.cargo/config");
- fs::create_dir_all(config_file.parent().unwrap()).unwrap();
- let mut config_file = File::create(config_file).unwrap();
- config_file.write_all(config.as_bytes()).unwrap();
-
- assert_that(p.cargo("build"),
- execs().with_status(101));
-}
-
-#[test]
-fn build_rustflags_recompile2() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", "");
- p.build();
-
- assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
- execs().with_status(0));
-
- // Setting RUSTFLAGS forces a recompile
- let config = r#"
- [build]
- rustflags = ["-Z", "bogus"]
- "#;
- let config_file = paths::root().join("foo/.cargo/config");
- fs::create_dir_all(config_file.parent().unwrap()).unwrap();
- let mut config_file = File::create(config_file).unwrap();
- config_file.write_all(config.as_bytes()).unwrap();
-
- assert_that(p.cargo("build"),
- execs().with_status(101));
-}
-
-#[test]
-fn build_rustflags_no_recompile() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", r#"
- [build]
- rustflags = ["--cfg", "foo"]
- "#);
- p.build();
-
- assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
- execs().with_status(0));
- assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
- execs().with_stdout("").with_status(0));
-}
+++ /dev/null
-use std::{env, str};
-use std::fs::{self, File};
-use std::io::Write;
-use std::net::TcpListener;
-use std::process::Stdio;
-use std::thread;
-
-use git2;
-use hamcrest::{assert_that, existing_file};
-
-use support::{execs, project};
-use support::git;
-use support::registry::Package;
-use test_cargo_install::{cargo_home, has_installed_exe};
-
-fn pkg(name: &str, vers: &str) {
- Package::new(name, vers)
- .file("src/main.rs", "fn main() {{}}")
- .publish();
-}
-
-#[test]
-fn multiple_installs() {
- let p = project("foo")
- .file("a/Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.0"
- "#)
- .file("a/src/main.rs", "fn main() {}")
- .file("b/Cargo.toml", r#"
- [package]
- name = "bar"
- authors = []
- version = "0.0.0"
- "#)
- .file("b/src/main.rs", "fn main() {}");
- p.build();
-
- let mut a = p.cargo("install").cwd(p.root().join("a")).build_command();
- let mut b = p.cargo("install").cwd(p.root().join("b")).build_command();
-
- a.stdout(Stdio::piped()).stderr(Stdio::piped());
- b.stdout(Stdio::piped()).stderr(Stdio::piped());
-
- let a = a.spawn().unwrap();
- let b = b.spawn().unwrap();
- let a = thread::spawn(move || a.wait_with_output().unwrap());
- let b = b.wait_with_output().unwrap();
- let a = a.join().unwrap();
-
- assert_that(a, execs().with_status(0));
- assert_that(b, execs().with_status(0));
-
- assert_that(cargo_home(), has_installed_exe("foo"));
- assert_that(cargo_home(), has_installed_exe("bar"));
-}
-
-#[test]
-fn concurrent_installs() {
- const LOCKED_BUILD: &'static str = "waiting for file lock on build directory";
-
- pkg("foo", "0.0.1");
- pkg("bar", "0.0.1");
-
- let mut a = ::cargo_process().arg("install").arg("foo").build_command();
- let mut b = ::cargo_process().arg("install").arg("bar").build_command();
-
- a.stdout(Stdio::piped()).stderr(Stdio::piped());
- b.stdout(Stdio::piped()).stderr(Stdio::piped());
-
- let a = a.spawn().unwrap();
- let b = b.spawn().unwrap();
- let a = thread::spawn(move || a.wait_with_output().unwrap());
- let b = b.wait_with_output().unwrap();
- let a = a.join().unwrap();
-
- assert!(!str::from_utf8(&a.stderr).unwrap().contains(LOCKED_BUILD));
- assert!(!str::from_utf8(&b.stderr).unwrap().contains(LOCKED_BUILD));
-
- assert_that(a, execs().with_status(0));
- assert_that(b, execs().with_status(0));
-
- assert_that(cargo_home(), has_installed_exe("foo"));
- assert_that(cargo_home(), has_installed_exe("bar"));
-}
-
-#[test]
-fn one_install_should_be_bad() {
- let p = project("foo")
- .file("a/Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.0"
- "#)
- .file("a/src/main.rs", "fn main() {}")
- .file("b/Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.0"
- "#)
- .file("b/src/main.rs", "fn main() {}");
- p.build();
-
- let mut a = p.cargo("install").cwd(p.root().join("a")).build_command();
- let mut b = p.cargo("install").cwd(p.root().join("b")).build_command();
-
- a.stdout(Stdio::piped()).stderr(Stdio::piped());
- b.stdout(Stdio::piped()).stderr(Stdio::piped());
-
- let a = a.spawn().unwrap();
- let b = b.spawn().unwrap();
- let a = thread::spawn(move || a.wait_with_output().unwrap());
- let b = b.wait_with_output().unwrap();
- let a = a.join().unwrap();
-
- let (bad, good) = if a.status.code() == Some(101) {(a, b)} else {(b, a)};
- assert_that(bad, execs().with_status(101).with_stderr_contains("\
-[ERROR] binary `foo[..]` already exists in destination as part of `[..]`
-"));
- assert_that(good, execs().with_status(0).with_stderr_contains("\
-warning: be sure to add `[..]` to your PATH [..]
-"));
-
- assert_that(cargo_home(), has_installed_exe("foo"));
-}
-
-#[test]
-fn multiple_registry_fetches() {
- let mut pkg = Package::new("bar", "1.0.2");
- for i in 0..10 {
- let name = format!("foo{}", i);
- Package::new(&name, "1.0.0").publish();
- pkg.dep(&name, "*");
- }
- pkg.publish();
-
- let p = project("foo")
- .file("a/Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.0"
-
- [dependencies]
- bar = "*"
- "#)
- .file("a/src/main.rs", "fn main() {}")
- .file("b/Cargo.toml", r#"
- [package]
- name = "bar"
- authors = []
- version = "0.0.0"
-
- [dependencies]
- bar = "*"
- "#)
- .file("b/src/main.rs", "fn main() {}");
- p.build();
-
- let mut a = p.cargo("build").cwd(p.root().join("a")).build_command();
- let mut b = p.cargo("build").cwd(p.root().join("b")).build_command();
-
- a.stdout(Stdio::piped()).stderr(Stdio::piped());
- b.stdout(Stdio::piped()).stderr(Stdio::piped());
-
- let a = a.spawn().unwrap();
- let b = b.spawn().unwrap();
- let a = thread::spawn(move || a.wait_with_output().unwrap());
- let b = b.wait_with_output().unwrap();
- let a = a.join().unwrap();
-
- assert_that(a, execs().with_status(0));
- assert_that(b, execs().with_status(0));
-
- let suffix = env::consts::EXE_SUFFIX;
- assert_that(&p.root().join("a/target/debug").join(format!("foo{}", suffix)),
- existing_file());
- assert_that(&p.root().join("b/target/debug").join(format!("bar{}", suffix)),
- existing_file());
-}
-
-#[test]
-fn git_same_repo_different_tags() {
- let a = git::new("dep", |project| {
- project.file("Cargo.toml", r#"
- [project]
- name = "dep"
- version = "0.5.0"
- authors = []
- "#).file("src/lib.rs", "pub fn tag1() {}")
- }).unwrap();
-
- let repo = git2::Repository::open(&a.root()).unwrap();
- git::tag(&repo, "tag1");
-
- File::create(a.root().join("src/lib.rs")).unwrap()
- .write_all(b"pub fn tag2() {}").unwrap();
- git::add(&repo);
- git::commit(&repo);
- git::tag(&repo, "tag2");
-
- let p = project("foo")
- .file("a/Cargo.toml", &format!(r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.0"
-
- [dependencies]
- dep = {{ git = '{}', tag = 'tag1' }}
- "#, a.url()))
- .file("a/src/main.rs", "extern crate dep; fn main() { dep::tag1(); }")
- .file("b/Cargo.toml", &format!(r#"
- [package]
- name = "bar"
- authors = []
- version = "0.0.0"
-
- [dependencies]
- dep = {{ git = '{}', tag = 'tag2' }}
- "#, a.url()))
- .file("b/src/main.rs", "extern crate dep; fn main() { dep::tag2(); }");
- p.build();
-
- let mut a = p.cargo("build").arg("-v").cwd(p.root().join("a")).build_command();
- let mut b = p.cargo("build").arg("-v").cwd(p.root().join("b")).build_command();
-
- a.stdout(Stdio::piped()).stderr(Stdio::piped());
- b.stdout(Stdio::piped()).stderr(Stdio::piped());
-
- let a = a.spawn().unwrap();
- let b = b.spawn().unwrap();
- let a = thread::spawn(move || a.wait_with_output().unwrap());
- let b = b.wait_with_output().unwrap();
- let a = a.join().unwrap();
-
- assert_that(a, execs().with_status(0));
- assert_that(b, execs().with_status(0));
-}
-
-#[test]
-fn git_same_branch_different_revs() {
- let a = git::new("dep", |project| {
- project.file("Cargo.toml", r#"
- [project]
- name = "dep"
- version = "0.5.0"
- authors = []
- "#).file("src/lib.rs", "pub fn f1() {}")
- }).unwrap();
-
- let p = project("foo")
- .file("a/Cargo.toml", &format!(r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.0"
-
- [dependencies]
- dep = {{ git = '{}' }}
- "#, a.url()))
- .file("a/src/main.rs", "extern crate dep; fn main() { dep::f1(); }")
- .file("b/Cargo.toml", &format!(r#"
- [package]
- name = "bar"
- authors = []
- version = "0.0.0"
-
- [dependencies]
- dep = {{ git = '{}' }}
- "#, a.url()))
- .file("b/src/main.rs", "extern crate dep; fn main() { dep::f2(); }");
- p.build();
-
- // Generate a Cargo.lock pointing at the current rev, then clear out the
- // target directory
- assert_that(p.cargo("build").cwd(p.root().join("a")),
- execs().with_status(0));
- fs::remove_dir_all(p.root().join("a/target")).unwrap();
-
- // Make a new commit on the master branch
- let repo = git2::Repository::open(&a.root()).unwrap();
- File::create(a.root().join("src/lib.rs")).unwrap()
- .write_all(b"pub fn f2() {}").unwrap();
- git::add(&repo);
- git::commit(&repo);
-
- // Now run both builds in parallel. The build of `b` should pick up the
- // newest commit while the build of `a` should use the locked old commit.
- let mut a = p.cargo("build").cwd(p.root().join("a")).build_command();
- let mut b = p.cargo("build").cwd(p.root().join("b")).build_command();
-
- a.stdout(Stdio::piped()).stderr(Stdio::piped());
- b.stdout(Stdio::piped()).stderr(Stdio::piped());
-
- let a = a.spawn().unwrap();
- let b = b.spawn().unwrap();
- let a = thread::spawn(move || a.wait_with_output().unwrap());
- let b = b.wait_with_output().unwrap();
- let a = a.join().unwrap();
-
- assert_that(a, execs().with_status(0));
- assert_that(b, execs().with_status(0));
-}
-
-#[test]
-fn same_project() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.0"
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("src/lib.rs", "");
- p.build();
-
- let mut a = p.cargo("build").build_command();
- let mut b = p.cargo("build").build_command();
-
- a.stdout(Stdio::piped()).stderr(Stdio::piped());
- b.stdout(Stdio::piped()).stderr(Stdio::piped());
-
- let a = a.spawn().unwrap();
- let b = b.spawn().unwrap();
- let a = thread::spawn(move || a.wait_with_output().unwrap());
- let b = b.wait_with_output().unwrap();
- let a = a.join().unwrap();
-
- assert_that(a, execs().with_status(0));
- assert_that(b, execs().with_status(0));
-}
-
-// Make sure that if Cargo dies while holding a lock that it's released and the
-// next Cargo to come in will take over cleanly.
-#[test]
-fn killing_cargo_releases_the_lock() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.0"
- build = "build.rs"
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("build.rs", r#"
- use std::net::TcpStream;
-
- fn main() {
- if std::env::var("A").is_ok() {
- TcpStream::connect(&std::env::var("ADDR").unwrap()[..])
- .unwrap();
- std::thread::sleep(std::time::Duration::new(10, 0));
- }
- }
- "#);
- p.build();
-
- // Our build script will connect to our local TCP socket to inform us that
- // it's started and that's how we know that `a` will have the lock
- // when we kill it.
- let l = TcpListener::bind("127.0.0.1:0").unwrap();
- let mut a = p.cargo("build").build_command();
- let mut b = p.cargo("build").build_command();
- a.stdout(Stdio::piped()).stderr(Stdio::piped());
- b.stdout(Stdio::piped()).stderr(Stdio::piped());
- a.env("ADDR", l.local_addr().unwrap().to_string()).env("A", "a");
- b.env("ADDR", l.local_addr().unwrap().to_string()).env_remove("A");
-
- // Spawn `a`, wait for it to get to the build script (at which point the
- // lock is held), then kill it.
- let mut a = a.spawn().unwrap();
- l.accept().unwrap();
- a.kill().unwrap();
-
- // Spawn `b`, then just finish the output of a/b the same way the above
- // tests does.
- let b = b.spawn().unwrap();
- let a = thread::spawn(move || a.wait_with_output().unwrap());
- let b = b.wait_with_output().unwrap();
- let a = a.join().unwrap();
-
- // We killed `a`, so it shouldn't succeed, but `b` should have succeeded.
- assert!(!a.status.success());
- assert_that(b, execs().with_status(0));
-}
-
-#[test]
-fn debug_release_ok() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.0"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- assert_that(p.cargo("build"), execs().with_status(0));
- fs::remove_dir_all(p.root().join("target")).unwrap();
-
- let mut a = p.cargo("build").build_command();
- let mut b = p.cargo("build").arg("--release").build_command();
- a.stdout(Stdio::piped()).stderr(Stdio::piped());
- b.stdout(Stdio::piped()).stderr(Stdio::piped());
- let a = a.spawn().unwrap();
- let b = b.spawn().unwrap();
- let a = thread::spawn(move || a.wait_with_output().unwrap());
- let b = b.wait_with_output().unwrap();
- let a = a.join().unwrap();
-
- assert_that(a, execs().with_status(0).with_stderr("\
-[COMPILING] foo v0.0.0 [..]
-"));
- assert_that(b, execs().with_status(0).with_stderr("\
-[COMPILING] foo v0.0.0 [..]
-"));
-}
+++ /dev/null
-use support::{project, execs};
-use hamcrest::assert_that;
-
-#[test]
-fn read_env_vars_for_config() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.0"
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", r#"
- use std::env;
- fn main() {
- assert_eq!(env::var("NUM_JOBS").unwrap(), "100");
- }
- "#);
-
- assert_that(p.cargo_process("build").env("CARGO_BUILD_JOBS", "100"),
- execs().with_status(0));
-}
+++ /dev/null
-use std::env;
-
-use support::{project, execs, basic_bin_manifest};
-use hamcrest::{assert_that, existing_file};
-use cargo::util::process;
-
-fn disabled() -> bool {
- // First, disable if ./configure requested so
- match env::var("CFG_DISABLE_CROSS_TESTS") {
- Ok(ref s) if *s == "1" => return true,
- _ => {}
- }
-
- // Right now the windows bots cannot cross compile due to the mingw setup,
- // so we disable ourselves on all but macos/linux setups where the rustc
- // install script ensures we have both architectures
- !(cfg!(target_os = "macos") ||
- cfg!(target_os = "linux") ||
- cfg!(target_env = "msvc"))
-}
-
-fn alternate() -> String {
- let platform = match env::consts::OS {
- "linux" => "unknown-linux-gnu",
- "macos" => "apple-darwin",
- "windows" => "pc-windows-msvc",
- _ => unreachable!(),
- };
- let arch = match env::consts::ARCH {
- "x86" => "x86_64",
- "x86_64" => "i686",
- _ => unreachable!(),
- };
- format!("{}-{}", arch, platform)
-}
-
-fn alternate_arch() -> &'static str {
- match env::consts::ARCH {
- "x86" => "x86_64",
- "x86_64" => "x86",
- _ => unreachable!(),
- }
-}
-
-fn host() -> String {
- let platform = match env::consts::OS {
- "linux" => "unknown-linux-gnu",
- "macos" => "apple-darwin",
- "windows" => "pc-windows-msvc",
- _ => unreachable!(),
- };
- let arch = match env::consts::ARCH {
- "x86" => "i686",
- "x86_64" => "x86_64",
- _ => unreachable!(),
- };
- format!("{}-{}", arch, platform)
-}
-
-#[test]
-fn simple_cross() {
- if disabled() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- build = "build.rs"
- "#)
- .file("build.rs", &format!(r#"
- fn main() {{
- assert_eq!(std::env::var("TARGET").unwrap(), "{}");
- }}
- "#, alternate()))
- .file("src/main.rs", &format!(r#"
- use std::env;
- fn main() {{
- assert_eq!(env::consts::ARCH, "{}");
- }}
- "#, alternate_arch()));
-
- let target = alternate();
- assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
- execs().with_status(0));
- assert_that(&p.target_bin(&target, "foo"), existing_file());
-
- assert_that(process(&p.target_bin(&target, "foo")),
- execs().with_status(0));
-}
-
-#[test]
-fn simple_cross_config() {
- if disabled() { return }
-
- let p = project("foo")
- .file(".cargo/config", &format!(r#"
- [build]
- target = "{}"
- "#, alternate()))
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- build = "build.rs"
- "#)
- .file("build.rs", &format!(r#"
- fn main() {{
- assert_eq!(std::env::var("TARGET").unwrap(), "{}");
- }}
- "#, alternate()))
- .file("src/main.rs", &format!(r#"
- use std::env;
- fn main() {{
- assert_eq!(env::consts::ARCH, "{}");
- }}
- "#, alternate_arch()));
-
- let target = alternate();
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
- assert_that(&p.target_bin(&target, "foo"), existing_file());
-
- assert_that(process(&p.target_bin(&target, "foo")),
- execs().with_status(0));
-}
-
-#[test]
-fn simple_deps() {
- if disabled() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "../bar"
- "#)
- .file("src/main.rs", r#"
- extern crate bar;
- fn main() { bar::bar(); }
- "#);
- let p2 = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn bar() {}");
- p2.build();
-
- let target = alternate();
- assert_that(p.cargo_process("build").arg("--target").arg(&target),
- execs().with_status(0));
- assert_that(&p.target_bin(&target, "foo"), existing_file());
-
- assert_that(process(&p.target_bin(&target, "foo")),
- execs().with_status(0));
-}
-
-#[test]
-fn plugin_deps() {
- if disabled() { return }
- if !::is_nightly() { return }
-
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "../bar"
-
- [dependencies.baz]
- path = "../baz"
- "#)
- .file("src/main.rs", r#"
- #![feature(plugin)]
- #![plugin(bar)]
- extern crate baz;
- fn main() {
- assert_eq!(bar!(), baz::baz());
- }
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "bar"
- plugin = true
- "#)
- .file("src/lib.rs", r#"
- #![feature(plugin_registrar, quote, rustc_private)]
-
- extern crate rustc_plugin;
- extern crate syntax;
-
- use rustc_plugin::Registry;
- use syntax::ast::TokenTree;
- use syntax::codemap::Span;
- use syntax::ext::base::{ExtCtxt, MacEager, MacResult};
-
- #[plugin_registrar]
- pub fn foo(reg: &mut Registry) {
- reg.register_macro("bar", expand_bar);
- }
-
- fn expand_bar(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
- -> Box<MacResult + 'static> {
- MacEager::expr(quote_expr!(cx, 1))
- }
- "#);
- let baz = project("baz")
- .file("Cargo.toml", r#"
- [package]
- name = "baz"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn baz() -> i32 { 1 }");
- bar.build();
- baz.build();
-
- let target = alternate();
- assert_that(foo.cargo_process("build").arg("--target").arg(&target),
- execs().with_status(0));
- assert_that(&foo.target_bin(&target, "foo"), existing_file());
-
- assert_that(process(&foo.target_bin(&target, "foo")),
- execs().with_status(0));
-}
-
-#[test]
-fn plugin_to_the_max() {
- if disabled() { return }
- if !::is_nightly() { return }
-
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "../bar"
-
- [dependencies.baz]
- path = "../baz"
- "#)
- .file("src/main.rs", r#"
- #![feature(plugin)]
- #![plugin(bar)]
- extern crate baz;
- fn main() {
- assert_eq!(bar!(), baz::baz());
- }
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "bar"
- plugin = true
-
- [dependencies.baz]
- path = "../baz"
- "#)
- .file("src/lib.rs", r#"
- #![feature(plugin_registrar, quote, rustc_private)]
-
- extern crate rustc_plugin;
- extern crate syntax;
- extern crate baz;
-
- use rustc_plugin::Registry;
- use syntax::ast::TokenTree;
- use syntax::codemap::Span;
- use syntax::ext::base::{ExtCtxt, MacEager, MacResult};
-
- #[plugin_registrar]
- pub fn foo(reg: &mut Registry) {
- reg.register_macro("bar", expand_bar);
- }
-
- fn expand_bar(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
- -> Box<MacResult + 'static> {
- MacEager::expr(quote_expr!(cx, baz::baz()))
- }
- "#);
- let baz = project("baz")
- .file("Cargo.toml", r#"
- [package]
- name = "baz"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn baz() -> i32 { 1 }");
- bar.build();
- baz.build();
-
- let target = alternate();
- assert_that(foo.cargo_process("build").arg("--target").arg(&target).arg("-v"),
- execs().with_status(0));
- println!("second");
- assert_that(foo.cargo("build").arg("-v")
- .arg("--target").arg(&target),
- execs().with_status(0));
- assert_that(&foo.target_bin(&target, "foo"), existing_file());
-
- assert_that(process(&foo.target_bin(&target, "foo")),
- execs().with_status(0));
-}
-
-#[test]
-fn linker_and_ar() {
- if disabled() { return }
-
- let target = alternate();
- let p = project("foo")
- .file(".cargo/config", &format!(r#"
- [target.{}]
- ar = "my-ar-tool"
- linker = "my-linker-tool"
- "#, target))
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &format!(r#"
- use std::env;
- fn main() {{
- assert_eq!(env::consts::ARCH, "{}");
- }}
- "#, alternate_arch()));
-
- assert_that(p.cargo_process("build").arg("--target").arg(&target)
- .arg("-v"),
- execs().with_status(101)
- .with_stderr_contains(&format!("\
-[COMPILING] foo v0.5.0 ({url})
-[RUNNING] `rustc src[..]foo.rs --crate-name foo --crate-type bin -g \
- --out-dir {dir}[..]target[..]{target}[..]debug \
- --emit=dep-info,link \
- --target {target} \
- -C ar=my-ar-tool -C linker=my-linker-tool \
- -L dependency={dir}[..]target[..]{target}[..]debug \
- -L dependency={dir}[..]target[..]{target}[..]debug[..]deps`
-",
- dir = p.root().display(),
- url = p.url(),
- target = target,
- )));
-}
-
-#[test]
-fn plugin_with_extra_dylib_dep() {
- if disabled() { return }
- if !::is_nightly() { return }
-
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "../bar"
- "#)
- .file("src/main.rs", r#"
- #![feature(plugin)]
- #![plugin(bar)]
-
- fn main() {}
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "bar"
- plugin = true
-
- [dependencies.baz]
- path = "../baz"
- "#)
- .file("src/lib.rs", r#"
- #![feature(plugin_registrar, rustc_private)]
-
- extern crate rustc_plugin;
- extern crate baz;
-
- use rustc_plugin::Registry;
-
- #[plugin_registrar]
- pub fn foo(reg: &mut Registry) {
- println!("{}", baz::baz());
- }
- "#);
- let baz = project("baz")
- .file("Cargo.toml", r#"
- [package]
- name = "baz"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "baz"
- crate_type = ["dylib"]
- "#)
- .file("src/lib.rs", "pub fn baz() -> i32 { 1 }");
- bar.build();
- baz.build();
-
- let target = alternate();
- assert_that(foo.cargo_process("build").arg("--target").arg(&target),
- execs().with_status(0));
-}
-
-#[test]
-fn cross_tests() {
- if disabled() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- authors = []
- version = "0.0.0"
-
- [[bin]]
- name = "bar"
- "#)
- .file("src/main.rs", &format!(r#"
- extern crate foo;
- use std::env;
- fn main() {{
- assert_eq!(env::consts::ARCH, "{}");
- }}
- #[test] fn test() {{ main() }}
- "#, alternate_arch()))
- .file("src/lib.rs", &format!(r#"
- use std::env;
- pub fn foo() {{ assert_eq!(env::consts::ARCH, "{}"); }}
- #[test] fn test_foo() {{ foo() }}
- "#, alternate_arch()));
-
- let target = alternate();
- assert_that(p.cargo_process("test").arg("--target").arg(&target),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.0 ({foo})
-[RUNNING] target[..]{triple}[..]bar-[..]
-[RUNNING] target[..]{triple}[..]foo-[..]", foo = p.url(), triple = target))
- .with_stdout("
-running 1 test
-test test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test test_foo ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn no_cross_doctests() {
- if disabled() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- authors = []
- version = "0.0.0"
- "#)
- .file("src/lib.rs", r#"
- //! ```
- //! extern crate foo;
- //! assert!(true);
- //! ```
- "#);
-
- let host_output = format!("\
-[COMPILING] foo v0.0.0 ({foo})
-[RUNNING] target[..]foo-[..]
-[DOCTEST] foo
-", foo = p.url());
-
- println!("a");
- assert_that(p.cargo_process("test"),
- execs().with_status(0)
- .with_stderr(&host_output));
-
- println!("b");
- let target = host();
- assert_that(p.cargo_process("test").arg("--target").arg(&target),
- execs().with_status(0)
- .with_stderr(&host_output));
-
- println!("c");
- let target = alternate();
- assert_that(p.cargo_process("test").arg("--target").arg(&target),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.0 ({foo})
-[RUNNING] target[..]{triple}[..]foo-[..]
-", foo = p.url(), triple = target)));
-}
-
-#[test]
-fn simple_cargo_run() {
- if disabled() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- "#)
- .file("src/main.rs", &format!(r#"
- use std::env;
- fn main() {{
- assert_eq!(env::consts::ARCH, "{}");
- }}
- "#, alternate_arch()));
-
- let target = alternate();
- assert_that(p.cargo_process("run").arg("--target").arg(&target),
- execs().with_status(0));
-}
-
-#[test]
-fn cross_with_a_build_script() {
- if disabled() { return }
-
- let target = alternate();
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- build = 'build.rs'
- "#)
- .file("build.rs", &format!(r#"
- use std::env;
- use std::path::PathBuf;
- fn main() {{
- assert_eq!(env::var("TARGET").unwrap(), "{0}");
- let mut path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
- assert_eq!(path.file_name().unwrap().to_str().unwrap(), "out");
- path.pop();
- assert!(path.file_name().unwrap().to_str().unwrap()
- .starts_with("foo-"));
- path.pop();
- assert_eq!(path.file_name().unwrap().to_str().unwrap(), "build");
- path.pop();
- assert_eq!(path.file_name().unwrap().to_str().unwrap(), "debug");
- path.pop();
- assert_eq!(path.file_name().unwrap().to_str().unwrap(), "{0}");
- path.pop();
- assert_eq!(path.file_name().unwrap().to_str().unwrap(), "target");
- }}
- "#, target))
- .file("src/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.0 (file://[..])
-[RUNNING] `rustc build.rs [..] --out-dir {dir}[..]target[..]build[..]foo-[..]`
-[RUNNING] `{dir}[..]target[..]build[..]foo-[..]build-script-build`
-[RUNNING] `rustc src[..]main.rs [..] --target {target} [..]`
-", target = target,
- dir = p.root().display())));
-}
-
-#[test]
-fn build_script_needed_for_host_and_target() {
- if disabled() { return }
-
- let target = alternate();
- let host = ::rustc_host();
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- build = 'build.rs'
-
- [dependencies.d1]
- path = "d1"
- [build-dependencies.d2]
- path = "d2"
- "#)
-
- .file("build.rs", r#"
- extern crate d2;
- fn main() { d2::d2(); }
- "#)
- .file("src/main.rs", "
- extern crate d1;
- fn main() { d1::d1(); }
- ")
- .file("d1/Cargo.toml", r#"
- [package]
- name = "d1"
- version = "0.0.0"
- authors = []
- build = 'build.rs'
- "#)
- .file("d1/src/lib.rs", "
- pub fn d1() {}
- ")
- .file("d1/build.rs", r#"
- use std::env;
- fn main() {
- let target = env::var("TARGET").unwrap();
- println!("cargo:rustc-flags=-L /path/to/{}", target);
- }
- "#)
- .file("d2/Cargo.toml", r#"
- [package]
- name = "d2"
- version = "0.0.0"
- authors = []
-
- [dependencies.d1]
- path = "../d1"
- "#)
- .file("d2/src/lib.rs", "
- extern crate d1;
- pub fn d2() { d1::d1(); }
- ");
-
- assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
- execs().with_status(0)
- .with_stderr_contains(&format!("\
-[COMPILING] d1 v0.0.0 ({url}/d1)", url = p.url()))
- .with_stderr_contains(&format!("\
-[RUNNING] `rustc d1[..]build.rs [..] --out-dir {dir}[..]target[..]build[..]d1-[..]`",
- dir = p.root().display()))
- .with_stderr_contains(&format!("\
-[RUNNING] `{dir}[..]target[..]build[..]d1-[..]build-script-build`",
- dir = p.root().display()))
- .with_stderr_contains("\
-[RUNNING] `rustc d1[..]src[..]lib.rs [..]`")
- .with_stderr_contains(&format!("\
-[COMPILING] d2 v0.0.0 ({url}/d2)", url = p.url()))
- .with_stderr_contains(&format!("\
-[RUNNING] `rustc d2[..]src[..]lib.rs [..] \
- -L /path/to/{host}`", host = host))
- .with_stderr_contains(&format!("\
-[COMPILING] foo v0.0.0 ({url})", url = p.url()))
- .with_stderr_contains(&format!("\
-[RUNNING] `rustc build.rs [..] --out-dir {dir}[..]target[..]build[..]foo-[..] \
- -L /path/to/{host}`", dir = p.root().display(), host = host))
- .with_stderr_contains(&format!("\
-[RUNNING] `rustc src[..]main.rs [..] --target {target} [..] \
- -L /path/to/{target}`", target = target)));
-}
-
-#[test]
-fn build_deps_for_the_right_arch() {
- if disabled() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
-
- [dependencies.d2]
- path = "d2"
- "#)
- .file("src/main.rs", "extern crate d2; fn main() {}")
- .file("d1/Cargo.toml", r#"
- [package]
- name = "d1"
- version = "0.0.0"
- authors = []
- "#)
- .file("d1/src/lib.rs", "
- pub fn d1() {}
- ")
- .file("d2/Cargo.toml", r#"
- [package]
- name = "d2"
- version = "0.0.0"
- authors = []
- build = "build.rs"
-
- [build-dependencies.d1]
- path = "../d1"
- "#)
- .file("d2/build.rs", "extern crate d1; fn main() {}")
- .file("d2/src/lib.rs", "");
-
- let target = alternate();
- assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn build_script_only_host() {
- if disabled() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- build = "build.rs"
-
- [build-dependencies.d1]
- path = "d1"
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("build.rs", "extern crate d1; fn main() {}")
- .file("d1/Cargo.toml", r#"
- [package]
- name = "d1"
- version = "0.0.0"
- authors = []
- build = "build.rs"
- "#)
- .file("d1/src/lib.rs", "
- pub fn d1() {}
- ")
- .file("d1/build.rs", r#"
- use std::env;
-
- fn main() {
- assert!(env::var("OUT_DIR").unwrap().replace("\\", "/")
- .contains("target/debug/build/d1-"),
- "bad: {:?}", env::var("OUT_DIR"));
- }
- "#);
-
- let target = alternate();
- assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn plugin_build_script_right_arch() {
- if disabled() { return }
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
-
- [lib]
- name = "foo"
- plugin = true
- "#)
- .file("build.rs", "fn main() {}")
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v").arg("--target").arg(alternate()),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] foo v0.0.1 ([..])
-[RUNNING] `rustc build.rs [..]`
-[RUNNING] `[..]build-script-build[..]`
-[RUNNING] `rustc src[..]lib.rs [..]`
-"));
-}
-
-#[test]
-fn build_script_with_platform_specific_dependencies() {
- if disabled() { return }
-
- let target = alternate();
- let host = ::rustc_host();
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
-
- [build-dependencies.d1]
- path = "d1"
- "#)
- .file("build.rs", "extern crate d1; fn main() {}")
- .file("src/lib.rs", "")
- .file("d1/Cargo.toml", &format!(r#"
- [package]
- name = "d1"
- version = "0.0.0"
- authors = []
-
- [target.{}.dependencies]
- d2 = {{ path = "../d2" }}
- "#, host))
- .file("d1/src/lib.rs", "extern crate d2;")
- .file("d2/Cargo.toml", r#"
- [package]
- name = "d2"
- version = "0.0.0"
- authors = []
- "#)
- .file("d2/src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v").arg("--target").arg(&target),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] d2 v0.0.0 ([..])
-[RUNNING] `rustc d2[..]src[..]lib.rs [..]`
-[COMPILING] d1 v0.0.0 ([..])
-[RUNNING] `rustc d1[..]src[..]lib.rs [..]`
-[COMPILING] foo v0.0.1 ([..])
-[RUNNING] `rustc build.rs [..]`
-[RUNNING] `{dir}[..]target[..]build[..]foo-[..]build-script-build`
-[RUNNING] `rustc src[..]lib.rs [..] --target {target} [..]`
-", dir = p.root().display(), target = target)));
-}
-
-#[test]
-fn platform_specific_dependencies_do_not_leak() {
- if disabled() { return }
-
- let target = alternate();
- let host = ::rustc_host();
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
-
- [dependencies.d1]
- path = "d1"
-
- [build-dependencies.d1]
- path = "d1"
- "#)
- .file("build.rs", "extern crate d1; fn main() {}")
- .file("src/lib.rs", "")
- .file("d1/Cargo.toml", &format!(r#"
- [package]
- name = "d1"
- version = "0.0.0"
- authors = []
-
- [target.{}.dependencies]
- d2 = {{ path = "../d2" }}
- "#, host))
- .file("d1/src/lib.rs", "extern crate d2;")
- .file("d2/Cargo.toml", r#"
- [package]
- name = "d2"
- version = "0.0.0"
- authors = []
- "#)
- .file("d2/src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v").arg("--target").arg(&target),
- execs().with_status(101)
- .with_stderr_contains("\
-[..] error: can't find crate for `d2`[..]"));
-}
-
-#[test]
-fn platform_specific_variables_reflected_in_build_scripts() {
- if disabled() { return }
-
- let target = alternate();
- let host = ::rustc_host();
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
-
- [target.{host}.dependencies]
- d1 = {{ path = "d1" }}
-
- [target.{target}.dependencies]
- d2 = {{ path = "d2" }}
- "#, host = host, target = target))
- .file("build.rs", &format!(r#"
- use std::env;
-
- fn main() {{
- let platform = env::var("TARGET").unwrap();
- let (expected, not_expected) = match &platform[..] {{
- "{host}" => ("DEP_D1_VAL", "DEP_D2_VAL"),
- "{target}" => ("DEP_D2_VAL", "DEP_D1_VAL"),
- _ => panic!("unknown platform")
- }};
-
- env::var(expected).ok()
- .expect(&format!("missing {{}}", expected));
- env::var(not_expected).err()
- .expect(&format!("found {{}}", not_expected));
- }}
- "#, host = host, target = target))
- .file("src/lib.rs", "")
- .file("d1/Cargo.toml", r#"
- [package]
- name = "d1"
- version = "0.0.0"
- authors = []
- links = "d1"
- build = "build.rs"
- "#)
- .file("d1/build.rs", r#"
- fn main() { println!("cargo:val=1") }
- "#)
- .file("d1/src/lib.rs", "")
- .file("d2/Cargo.toml", r#"
- [package]
- name = "d2"
- version = "0.0.0"
- authors = []
- links = "d2"
- build = "build.rs"
- "#)
- .file("d2/build.rs", r#"
- fn main() { println!("cargo:val=1") }
- "#)
- .file("d2/src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0));
- assert_that(p.cargo_process("build").arg("-v").arg("--target").arg(&target),
- execs().with_status(0));
-}
+++ /dev/null
-use std::net::TcpListener;
-use std::io::{self, Read};
-use std::process::{Stdio, Child};
-
-use support::project;
-
-#[cfg(unix)]
-fn enabled() -> bool {
- true
-}
-
-// On Windows suport for these tests is only enabled through the usage of job
-// objects. Support for nested job objects, however, was added in recent-ish
-// versions of Windows, so this test may not always be able to succeed.
-//
-// As a result, we try to add ourselves to a job object here
-// can succeed or not.
-#[cfg(windows)]
-fn enabled() -> bool {
- use kernel32;
- use winapi;
- unsafe {
- // If we're not currently in a job, then we can definitely run these
- // tests.
- let me = kernel32::GetCurrentProcess();
- let mut ret = 0;
- let r = kernel32::IsProcessInJob(me, 0 as *mut _, &mut ret);
- assert!(r != 0);
- if ret == winapi::FALSE {
- return true
- }
-
- // If we are in a job, then we can run these tests if we can be added to
- // a nested job (as we're going to create a nested job no matter what as
- // part of these tests.
- //
- // If we can't be added to a nested job, then these tests will
- // definitely fail, and there's not much we can do about that.
- let job = kernel32::CreateJobObjectW(0 as *mut _, 0 as *const _);
- assert!(!job.is_null());
- let r = kernel32::AssignProcessToJobObject(job, me);
- kernel32::CloseHandle(job);
- r != 0
- }
-}
-
-#[test]
-fn ctrl_c_kills_everyone() {
- if !enabled() {
- return
- }
-
- let listener = TcpListener::bind("127.0.0.1:0").unwrap();
- let addr = listener.local_addr().unwrap();
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- "#)
- .file("src/lib.rs", "")
- .file("build.rs", &format!(r#"
- use std::net::TcpStream;
- use std::io::Read;
-
- fn main() {{
- let mut socket = TcpStream::connect("{}").unwrap();
- let _ = socket.read(&mut [0; 10]);
- panic!("that read should never return");
- }}
- "#, addr));
- p.build();
-
- let mut cargo = p.cargo("build").build_command();
- cargo.stdin(Stdio::piped())
- .stdout(Stdio::piped())
- .stderr(Stdio::piped())
- .env("__CARGO_TEST_SETSID_PLEASE_DONT_USE_ELSEWHERE", "1");
- let mut child = cargo.spawn().unwrap();
-
- let mut sock = listener.accept().unwrap().0;
- ctrl_c(&mut child);
-
- assert!(!child.wait().unwrap().success());
- match sock.read(&mut [0; 10]) {
- Ok(n) => assert_eq!(n, 0),
- Err(e) => assert_eq!(e.kind(), io::ErrorKind::ConnectionReset),
- }
-}
-
-#[cfg(unix)]
-fn ctrl_c(child: &mut Child) {
- use libc;
-
- let r = unsafe { libc::kill(-(child.id() as i32), libc::SIGINT) };
- if r < 0 {
- panic!("failed to kill: {}", io::Error::last_os_error());
- }
-}
-
-#[cfg(windows)]
-fn ctrl_c(child: &mut Child) {
- child.kill().unwrap();
-}
+++ /dev/null
-use std::str;
-use std::fs;
-
-use support::{project, execs, path2url};
-use hamcrest::{assert_that, existing_file, existing_dir, is_not};
-
-#[test]
-fn simple() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- "#)
- .file("build.rs", "fn main() {}")
- .file("src/lib.rs", r#"
- pub fn foo() {}
- "#);
-
- assert_that(p.cargo_process("doc"),
- execs().with_status(0).with_stderr(&format!("\
-[..] foo v0.0.1 ({dir})
-[..] foo v0.0.1 ({dir})
-",
- dir = path2url(p.root()))));
- assert_that(&p.root().join("target/doc"), existing_dir());
- assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
-}
-
-#[test]
-fn doc_no_libs() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [[bin]]
- name = "foo"
- doc = false
- "#)
- .file("src/main.rs", r#"
- bad code
- "#);
-
- assert_that(p.cargo_process("doc"),
- execs().with_status(0));
-}
-
-#[test]
-fn doc_twice() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- pub fn foo() {}
- "#);
-
- assert_that(p.cargo_process("doc"),
- execs().with_status(0).with_stderr(&format!("\
-[DOCUMENTING] foo v0.0.1 ({dir})
-",
- dir = path2url(p.root()))));
-
- assert_that(p.cargo("doc"),
- execs().with_status(0).with_stdout(""))
-}
-
-#[test]
-fn doc_deps() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/lib.rs", r#"
- extern crate bar;
- pub fn foo() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", r#"
- pub fn bar() {}
- "#);
-
- assert_that(p.cargo_process("doc"),
- execs().with_status(0).with_stderr(&format!("\
-[..] bar v0.0.1 ({dir}/bar)
-[..] bar v0.0.1 ({dir}/bar)
-[DOCUMENTING] foo v0.0.1 ({dir})
-",
- dir = path2url(p.root()))));
-
- assert_that(&p.root().join("target/doc"), existing_dir());
- assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
- assert_that(&p.root().join("target/doc/bar/index.html"), existing_file());
-
- assert_that(p.cargo("doc")
- .env("RUST_LOG", "cargo::ops::cargo_rustc::fingerprint"),
- execs().with_status(0).with_stdout(""));
-
- assert_that(&p.root().join("target/doc"), existing_dir());
- assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
- assert_that(&p.root().join("target/doc/bar/index.html"), existing_file());
-}
-
-#[test]
-fn doc_no_deps() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/lib.rs", r#"
- extern crate bar;
- pub fn foo() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", r#"
- pub fn bar() {}
- "#);
-
- assert_that(p.cargo_process("doc").arg("--no-deps"),
- execs().with_status(0).with_stderr(&format!("\
-[COMPILING] bar v0.0.1 ({dir}/bar)
-[DOCUMENTING] foo v0.0.1 ({dir})
-",
- dir = path2url(p.root()))));
-
- assert_that(&p.root().join("target/doc"), existing_dir());
- assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
- assert_that(&p.root().join("target/doc/bar/index.html"), is_not(existing_file()));
-}
-
-#[test]
-fn doc_only_bin() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/main.rs", r#"
- extern crate bar;
- pub fn foo() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", r#"
- pub fn bar() {}
- "#);
-
- assert_that(p.cargo_process("doc").arg("-v"),
- execs().with_status(0));
-
- assert_that(&p.root().join("target/doc"), existing_dir());
- assert_that(&p.root().join("target/doc/bar/index.html"), existing_file());
- assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
-}
-
-#[test]
-fn doc_lib_bin_same_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("src/lib.rs", "fn foo() {}");
-
- assert_that(p.cargo_process("doc"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] cannot document a package where a library and a binary have the same name. \
-Consider renaming one or marking the target as `doc = false`
-"));
-}
-
-#[test]
-fn doc_dash_p() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.a]
- path = "a"
- "#)
- .file("src/lib.rs", "extern crate a;")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [dependencies.b]
- path = "../b"
- "#)
- .file("a/src/lib.rs", "extern crate b;")
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.0.1"
- authors = []
- "#)
- .file("b/src/lib.rs", "");
-
- assert_that(p.cargo_process("doc").arg("-p").arg("a"),
- execs().with_status(0)
- .with_stderr("\
-[..] b v0.0.1 (file://[..])
-[..] b v0.0.1 (file://[..])
-[DOCUMENTING] a v0.0.1 (file://[..])
-"));
-}
-
-#[test]
-fn doc_same_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file("src/bin/main.rs", "fn main() {}")
- .file("examples/main.rs", "fn main() {}")
- .file("tests/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("doc"),
- execs().with_status(0));
-}
-
-#[test]
-fn doc_target() {
- const TARGET: &'static str = "arm-unknown-linux-gnueabihf";
-
- if !::is_nightly() { return }
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- #![feature(no_core)]
- #![no_core]
-
- extern {
- pub static A: u32;
- }
- "#);
-
- assert_that(p.cargo_process("doc").arg("--target").arg(TARGET).arg("--verbose"),
- execs().with_status(0));
- assert_that(&p.root().join(&format!("target/{}/doc", TARGET)), existing_dir());
- assert_that(&p.root().join(&format!("target/{}/doc/foo/index.html", TARGET)), existing_file());
-}
-
-#[test]
-fn target_specific_not_documented() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [target.foo.dependencies]
- a = { path = "a" }
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
- "#)
- .file("a/src/lib.rs", "not rust");
-
- assert_that(p.cargo_process("doc"),
- execs().with_status(0));
-}
-
-#[test]
-fn output_not_captured() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- a = { path = "a" }
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
- "#)
- .file("a/src/lib.rs", "
- /// ```
- /// ☃
- /// ```
- pub fn foo() {}
- ");
-
- let output = p.cargo_process("doc").exec_with_output().err().unwrap()
- .output.unwrap();
- let stderr = str::from_utf8(&output.stderr).unwrap();
- assert!(stderr.contains("☃"), "no snowman\n{}", stderr);
- assert!(stderr.contains("unknown start of token"), "no message\n{}", stderr);
-}
-
-#[test]
-fn target_specific_documented() {
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [target.foo.dependencies]
- a = {{ path = "a" }}
- [target.{}.dependencies]
- a = {{ path = "a" }}
- "#, ::rustc_host()))
- .file("src/lib.rs", "
- extern crate a;
-
- /// test
- pub fn foo() {}
- ")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
- "#)
- .file("a/src/lib.rs", "
- /// test
- pub fn foo() {}
- ");
-
- assert_that(p.cargo_process("doc"),
- execs().with_status(0));
-}
-
-#[test]
-fn no_document_build_deps() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [build-dependencies]
- a = { path = "a" }
- "#)
- .file("src/lib.rs", "
- pub fn foo() {}
- ")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
- "#)
- .file("a/src/lib.rs", "
- /// ```
- /// ☃
- /// ```
- pub fn foo() {}
- ");
-
- assert_that(p.cargo_process("doc"),
- execs().with_status(0));
-}
-
-#[test]
-fn doc_release() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("--release"),
- execs().with_status(0));
- assert_that(p.cargo("doc").arg("--release").arg("-v"),
- execs().with_status(0)
- .with_stderr("\
-[DOCUMENTING] foo v0.0.1 ([..])
-[RUNNING] `rustdoc src[..]lib.rs [..]`
-"));
-}
-
-#[test]
-fn doc_multiple_deps() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "bar"
-
- [dependencies.baz]
- path = "baz"
- "#)
- .file("src/lib.rs", r#"
- extern crate bar;
- pub fn foo() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", r#"
- pub fn bar() {}
- "#)
- .file("baz/Cargo.toml", r#"
- [package]
- name = "baz"
- version = "0.0.1"
- authors = []
- "#)
- .file("baz/src/lib.rs", r#"
- pub fn baz() {}
- "#);
-
- assert_that(p.cargo_process("doc")
- .arg("-p").arg("bar")
- .arg("-p").arg("baz")
- .arg("-v"),
- execs().with_status(0));
-
- assert_that(&p.root().join("target/doc"), existing_dir());
- assert_that(&p.root().join("target/doc/bar/index.html"), existing_file());
- assert_that(&p.root().join("target/doc/baz/index.html"), existing_file());
-}
-
-#[test]
-fn features() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "bar"
-
- [features]
- foo = ["bar/bar"]
- "#)
- .file("src/lib.rs", r#"
- #[cfg(feature = "foo")]
- pub fn foo() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [features]
- bar = []
- "#)
- .file("bar/build.rs", r#"
- fn main() {
- println!("cargo:rustc-cfg=bar");
- }
- "#)
- .file("bar/src/lib.rs", r#"
- #[cfg(feature = "bar")]
- pub fn bar() {}
- "#);
- assert_that(p.cargo_process("doc").arg("--features").arg("foo"),
- execs().with_status(0));
- assert_that(&p.root().join("target/doc"), existing_dir());
- assert_that(&p.root().join("target/doc/foo/fn.foo.html"), existing_file());
- assert_that(&p.root().join("target/doc/bar/fn.bar.html"), existing_file());
-}
-
-#[test]
-fn rerun_when_dir_removed() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- /// dox
- pub fn foo() {}
- "#);
- assert_that(p.cargo_process("doc"),
- execs().with_status(0));
- assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
-
- fs::remove_dir_all(p.root().join("target/doc/foo")).unwrap();
-
- assert_that(p.cargo_process("doc"),
- execs().with_status(0));
- assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
-}
-
-#[test]
-fn document_only_lib() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- /// dox
- pub fn foo() {}
- "#)
- .file("src/bin/bar.rs", r#"
- /// ```
- /// ☃
- /// ```
- pub fn foo() {}
- fn main() { foo(); }
- "#);
- assert_that(p.cargo_process("doc").arg("--lib"),
- execs().with_status(0));
- assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
-}
+++ /dev/null
-use std::fs::File;
-use std::io::prelude::*;
-
-use support::{project, execs};
-use support::paths::CargoPathExt;
-use hamcrest::assert_that;
-
-#[test]
-fn invalid1() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [features]
- bar = ["baz"]
- "#)
- .file("src/main.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- Feature `bar` includes `baz` which is neither a dependency nor another feature
-"));
-}
-
-#[test]
-fn invalid2() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [features]
- bar = ["baz"]
-
- [dependencies.bar]
- path = "foo"
- "#)
- .file("src/main.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- Features and dependencies cannot have the same name: `bar`
-"));
-}
-
-#[test]
-fn invalid3() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [features]
- bar = ["baz"]
-
- [dependencies.baz]
- path = "foo"
- "#)
- .file("src/main.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- Feature `bar` depends on `baz` which is not an optional dependency.
-Consider adding `optional = true` to the dependency
-"));
-}
-
-#[test]
-fn invalid4() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "bar"
- features = ["bar"]
- "#)
- .file("src/main.rs", "")
- .file("bar/Cargo.toml", r#"
- [project]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[ERROR] Package `bar v0.0.1 ([..])` does not have these features: `bar`
-"));
-
- let p = p.file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#);
-
- assert_that(p.cargo_process("build").arg("--features").arg("test"),
- execs().with_status(101).with_stderr("\
-[ERROR] Package `foo v0.0.1 ([..])` does not have these features: `test`
-"));
-}
-
-#[test]
-fn invalid5() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dev-dependencies.bar]
- path = "bar"
- optional = true
- "#)
- .file("src/main.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- Dev-dependencies are not allowed to be optional: `bar`
-"));
-}
-
-#[test]
-fn invalid6() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [features]
- foo = ["bar/baz"]
- "#)
- .file("src/main.rs", "");
-
- assert_that(p.cargo_process("build").arg("--features").arg("foo"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- Feature `foo` requires `bar` which is not an optional dependency
-"));
-}
-
-#[test]
-fn invalid7() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [features]
- foo = ["bar/baz"]
- bar = []
- "#)
- .file("src/main.rs", "");
-
- assert_that(p.cargo_process("build").arg("--features").arg("foo"),
- execs().with_status(101).with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- Feature `foo` requires `bar` which is not an optional dependency
-"));
-}
-
-#[test]
-fn invalid8() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "bar"
- features = ["foo/bar"]
- "#)
- .file("src/main.rs", "")
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", "");
-
- assert_that(p.cargo_process("build").arg("--features").arg("foo"),
- execs().with_status(101).with_stderr("\
-[ERROR] features in dependencies cannot enable features in other dependencies: `foo/bar`
-"));
-}
-
-#[test]
-fn no_feature_doesnt_build() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "bar"
- optional = true
- "#)
- .file("src/main.rs", r#"
- #[cfg(feature = "bar")]
- extern crate bar;
- #[cfg(feature = "bar")]
- fn main() { bar::bar(); println!("bar") }
- #[cfg(not(feature = "bar"))]
- fn main() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", "pub fn bar() {}");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({dir})
-", dir = p.url())));
- assert_that(p.process(&p.bin("foo")),
- execs().with_status(0).with_stdout(""));
-
- assert_that(p.cargo("build").arg("--features").arg("bar"),
- execs().with_status(0).with_stderr(format!("\
-[COMPILING] bar v0.0.1 ({dir}/bar)
-[COMPILING] foo v0.0.1 ({dir})
-", dir = p.url())));
- assert_that(p.process(&p.bin("foo")),
- execs().with_status(0).with_stdout("bar\n"));
-}
-
-#[test]
-fn default_feature_pulled_in() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [features]
- default = ["bar"]
-
- [dependencies.bar]
- path = "bar"
- optional = true
- "#)
- .file("src/main.rs", r#"
- #[cfg(feature = "bar")]
- extern crate bar;
- #[cfg(feature = "bar")]
- fn main() { bar::bar(); println!("bar") }
- #[cfg(not(feature = "bar"))]
- fn main() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", "pub fn bar() {}");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr(format!("\
-[COMPILING] bar v0.0.1 ({dir}/bar)
-[COMPILING] foo v0.0.1 ({dir})
-", dir = p.url())));
- assert_that(p.process(&p.bin("foo")),
- execs().with_status(0).with_stdout("bar\n"));
-
- assert_that(p.cargo("build").arg("--no-default-features"),
- execs().with_status(0).with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({dir})
-", dir = p.url())));
- assert_that(p.process(&p.bin("foo")),
- execs().with_status(0).with_stdout(""));
-}
-
-#[test]
-fn cyclic_feature() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [features]
- default = ["default"]
- "#)
- .file("src/main.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[ERROR] Cyclic feature dependency: feature `default` depends on itself
-"));
-}
-
-#[test]
-fn cyclic_feature2() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [features]
- foo = ["bar"]
- bar = ["foo"]
- "#)
- .file("src/main.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[ERROR] Cyclic feature dependency: feature `[..]` depends on itself
-"));
-}
-
-#[test]
-fn groups_on_groups_on_groups() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [features]
- default = ["f1"]
- f1 = ["f2", "bar"]
- f2 = ["f3", "f4"]
- f3 = ["f5", "f6", "baz"]
- f4 = ["f5", "f7"]
- f5 = ["f6"]
- f6 = ["f7"]
- f7 = ["bar"]
-
- [dependencies.bar]
- path = "bar"
- optional = true
-
- [dependencies.baz]
- path = "baz"
- optional = true
- "#)
- .file("src/main.rs", r#"
- extern crate bar;
- extern crate baz;
- fn main() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", "pub fn bar() {}")
- .file("baz/Cargo.toml", r#"
- [package]
- name = "baz"
- version = "0.0.1"
- authors = []
- "#)
- .file("baz/src/lib.rs", "pub fn baz() {}");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr(format!("\
-[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
-[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
-[COMPILING] foo v0.0.1 ({dir})
-", dir = p.url())));
-}
-
-#[test]
-fn many_cli_features() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "bar"
- optional = true
-
- [dependencies.baz]
- path = "baz"
- optional = true
- "#)
- .file("src/main.rs", r#"
- extern crate bar;
- extern crate baz;
- fn main() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", "pub fn bar() {}")
- .file("baz/Cargo.toml", r#"
- [package]
- name = "baz"
- version = "0.0.1"
- authors = []
- "#)
- .file("baz/src/lib.rs", "pub fn baz() {}");
-
- assert_that(p.cargo_process("build").arg("--features").arg("bar baz"),
- execs().with_status(0).with_stderr(format!("\
-[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
-[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
-[COMPILING] foo v0.0.1 ({dir})
-", dir = p.url())));
-}
-
-#[test]
-fn union_features() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.d1]
- path = "d1"
- features = ["f1"]
- [dependencies.d2]
- path = "d2"
- features = ["f2"]
- "#)
- .file("src/main.rs", r#"
- extern crate d1;
- extern crate d2;
- fn main() {
- d2::f1();
- d2::f2();
- }
- "#)
- .file("d1/Cargo.toml", r#"
- [package]
- name = "d1"
- version = "0.0.1"
- authors = []
-
- [features]
- f1 = ["d2"]
-
- [dependencies.d2]
- path = "../d2"
- features = ["f1"]
- optional = true
- "#)
- .file("d1/src/lib.rs", "")
- .file("d2/Cargo.toml", r#"
- [package]
- name = "d2"
- version = "0.0.1"
- authors = []
-
- [features]
- f1 = []
- f2 = []
- "#)
- .file("d2/src/lib.rs", r#"
- #[cfg(feature = "f1")] pub fn f1() {}
- #[cfg(feature = "f2")] pub fn f2() {}
- "#);
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr(format!("\
-[COMPILING] d2 v0.0.1 ({dir}/d2)
-[COMPILING] d1 v0.0.1 ({dir}/d1)
-[COMPILING] foo v0.0.1 ({dir})
-", dir = p.url())));
-}
-
-#[test]
-fn many_features_no_rebuilds() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.1.0"
- authors = []
-
- [dependencies.a]
- path = "a"
- features = ["fall"]
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.1.0"
- authors = []
-
- [features]
- ftest = []
- ftest2 = []
- fall = ["ftest", "ftest2"]
- "#)
- .file("a/src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr(format!("\
-[COMPILING] a v0.1.0 ({dir}/a)
-[COMPILING] b v0.1.0 ({dir})
-", dir = p.url())));
- p.root().move_into_the_past().unwrap();
-
- assert_that(p.cargo("build").arg("-v"),
- execs().with_status(0).with_stderr("\
-[FRESH] a v0.1.0 ([..]/a)
-[FRESH] b v0.1.0 ([..])
-"));
-}
-
-// Tests that all cmd lines work with `--features ""`
-#[test]
-fn empty_features() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("build").arg("--features").arg(""),
- execs().with_status(0));
-}
-
-// Tests that all cmd lines work with `--features ""`
-#[test]
-fn transitive_features() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [features]
- foo = ["bar/baz"]
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/main.rs", "
- extern crate bar;
- fn main() { bar::baz(); }
- ")
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [features]
- baz = []
- "#)
- .file("bar/src/lib.rs", r#"
- #[cfg(feature = "baz")]
- pub fn baz() {}
- "#);
-
- assert_that(p.cargo_process("build").arg("--features").arg("foo"),
- execs().with_status(0));
-}
-
-#[test]
-fn everything_in_the_lockfile() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [features]
- f1 = ["d1/f1"]
- f2 = ["d2"]
-
- [dependencies.d1]
- path = "d1"
- [dependencies.d2]
- path = "d2"
- optional = true
- [dependencies.d3]
- path = "d3"
- optional = true
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("d1/Cargo.toml", r#"
- [package]
- name = "d1"
- version = "0.0.1"
- authors = []
-
- [features]
- f1 = []
- "#)
- .file("d1/src/lib.rs", "")
- .file("d2/Cargo.toml", r#"
- [package]
- name = "d2"
- version = "0.0.2"
- authors = []
- "#)
- .file("d2/src/lib.rs", "")
- .file("d3/Cargo.toml", r#"
- [package]
- name = "d3"
- version = "0.0.3"
- authors = []
-
- [features]
- f3 = []
- "#)
- .file("d3/src/lib.rs", "");
-
- assert_that(p.cargo_process("fetch"), execs().with_status(0));
- let loc = p.root().join("Cargo.lock");
- let mut lockfile = String::new();
- File::open(&loc).unwrap().read_to_string(&mut lockfile).unwrap();
- assert!(lockfile.contains(r#"name = "d1""#), "d1 not found\n{}", lockfile);
- assert!(lockfile.contains(r#"name = "d2""#), "d2 not found\n{}", lockfile);
- assert!(lockfile.contains(r#"name = "d3""#), "d3 not found\n{}", lockfile);
-}
-
-#[test]
-fn no_rebuild_when_frobbing_default_feature() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
-
- [dependencies]
- a = { path = "a" }
- b = { path = "b" }
- "#)
- .file("src/lib.rs", "")
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.1.0"
- authors = []
-
- [dependencies]
- a = { path = "../a", features = ["f1"], default-features = false }
- "#)
- .file("b/src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.1.0"
- authors = []
-
- [features]
- default = ["f1"]
- f1 = []
- "#)
- .file("a/src/lib.rs", "");
-
- assert_that(p.cargo_process("build"), execs().with_status(0));
- assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
- assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
-}
-
-#[test]
-fn unions_work_with_no_default_features() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
-
- [dependencies]
- a = { path = "a" }
- b = { path = "b" }
- "#)
- .file("src/lib.rs", r#"
- extern crate a;
- pub fn foo() { a::a(); }
- "#)
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.1.0"
- authors = []
-
- [dependencies]
- a = { path = "../a", features = [], default-features = false }
- "#)
- .file("b/src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.1.0"
- authors = []
-
- [features]
- default = ["f1"]
- f1 = []
- "#)
- .file("a/src/lib.rs", r#"
- #[cfg(feature = "f1")]
- pub fn a() {}
- "#);
-
- assert_that(p.cargo_process("build"), execs().with_status(0));
- assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
- assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
-}
-
-#[test]
-fn optional_and_dev_dep() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "test"
- version = "0.1.0"
- authors = []
-
- [dependencies]
- foo = { path = "foo", optional = true }
- [dev-dependencies]
- foo = { path = "foo" }
- "#)
- .file("src/lib.rs", "")
- .file("foo/Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("foo/src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr("\
-[COMPILING] test v0.1.0 ([..])
-"));
-}
-
-#[test]
-fn activating_feature_activates_dep() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "test"
- version = "0.1.0"
- authors = []
-
- [dependencies]
- foo = { path = "foo", optional = true }
-
- [features]
- a = ["foo/a"]
- "#)
- .file("src/lib.rs", "
- extern crate foo;
- pub fn bar() {
- foo::bar();
- }
- ")
- .file("foo/Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
-
- [features]
- a = []
- "#)
- .file("foo/src/lib.rs", r#"
- #[cfg(feature = "a")]
- pub fn bar() {}
- "#);
-
- assert_that(p.cargo_process("build").arg("--features").arg("a").arg("-v"),
- execs().with_status(0));
-}
+++ /dev/null
-use support::{project, execs};
-use hamcrest::assert_that;
-
-#[test]
-fn no_deps() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
- "#)
- .file("src/main.rs", r#"
- mod a; fn main() {}
- "#)
- .file("src/a.rs", "");
-
- assert_that(p.cargo_process("fetch"),
- execs().with_status(0).with_stdout(""));
-}
+++ /dev/null
-use std::fs::{self, File};
-use std::io::prelude::*;
-
-use support::{project, execs, path2url};
-use support::paths::CargoPathExt;
-use hamcrest::{assert_that, existing_file};
-
-#[test]
-fn modifying_and_moving() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
- "#)
- .file("src/main.rs", r#"
- mod a; fn main() {}
- "#)
- .file("src/a.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({dir})
-", dir = path2url(p.root()))));
-
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stdout(""));
- p.root().move_into_the_past().unwrap();
- p.root().join("target").move_into_the_past().unwrap();
-
- File::create(&p.root().join("src/a.rs")).unwrap()
- .write_all(b"#[allow(unused)]fn main() {}").unwrap();
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({dir})
-", dir = path2url(p.root()))));
-
- fs::rename(&p.root().join("src/a.rs"), &p.root().join("src/b.rs")).unwrap();
- assert_that(p.cargo("build"),
- execs().with_status(101));
-}
-
-#[test]
-fn modify_only_some_files() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
- "#)
- .file("src/lib.rs", "mod a;")
- .file("src/a.rs", "")
- .file("src/main.rs", r#"
- mod b;
- fn main() {}
- "#)
- .file("src/b.rs", "")
- .file("tests/test.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({dir})
-", dir = path2url(p.root()))));
- assert_that(p.cargo("test"),
- execs().with_status(0));
- ::sleep_ms(1000);
-
- assert_that(&p.bin("foo"), existing_file());
-
- let lib = p.root().join("src/lib.rs");
- let bin = p.root().join("src/b.rs");
-
- File::create(&lib).unwrap().write_all(b"invalid rust code").unwrap();
- File::create(&bin).unwrap().write_all(b"#[allow(unused)]fn foo() {}").unwrap();
- lib.move_into_the_past().unwrap();
-
- // Make sure the binary is rebuilt, not the lib
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({dir})
-", dir = path2url(p.root()))));
- assert_that(&p.bin("foo"), existing_file());
-}
-
-#[test]
-fn rebuild_sub_package_then_while_package() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
-
- [dependencies.a]
- path = "a"
- [dependencies.b]
- path = "b"
- "#)
- .file("src/lib.rs", "extern crate a; extern crate b;")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- authors = []
- version = "0.0.1"
- [dependencies.b]
- path = "../b"
- "#)
- .file("a/src/lib.rs", "extern crate b;")
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- authors = []
- version = "0.0.1"
- "#)
- .file("b/src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0));
-
- File::create(&p.root().join("b/src/lib.rs")).unwrap().write_all(br#"
- pub fn b() {}
- "#).unwrap();
-
- assert_that(p.cargo("build").arg("-pb"),
- execs().with_status(0));
-
- File::create(&p.root().join("src/lib.rs")).unwrap().write_all(br#"
- extern crate a;
- extern crate b;
- pub fn toplevel() {}
- "#).unwrap();
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn changing_features_is_ok() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
-
- [features]
- foo = []
- "#)
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0)
- .with_stderr("\
-[..]Compiling foo v0.0.1 ([..])
-"));
-
- assert_that(p.cargo("build").arg("--features").arg("foo"),
- execs().with_status(0)
- .with_stderr("\
-[..]Compiling foo v0.0.1 ([..])
-"));
-
- assert_that(p.cargo("build"),
- execs().with_status(0)
- .with_stderr("\
-[..]Compiling foo v0.0.1 ([..])
-"));
-
- assert_that(p.cargo("build"),
- execs().with_status(0)
- .with_stdout(""));
-}
-
-#[test]
-fn rebuild_tests_if_lib_changes() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn foo() {}")
- .file("tests/foo.rs", r#"
- extern crate foo;
- #[test]
- fn test() { foo::foo(); }
- "#);
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0));
- assert_that(p.cargo("test"),
- execs().with_status(0));
-
- File::create(&p.root().join("src/lib.rs")).unwrap();
- p.root().move_into_the_past().unwrap();
- p.root().join("target").move_into_the_past().unwrap();
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
- assert_that(p.cargo("test").arg("-v"),
- execs().with_status(101));
-}
-
-#[test]
-fn no_rebuild_transitive_target_deps() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- a = { path = "a" }
- [dev-dependencies]
- b = { path = "b" }
- "#)
- .file("src/lib.rs", "")
- .file("tests/foo.rs", "")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [target.foo.dependencies]
- c = { path = "../c" }
- "#)
- .file("a/src/lib.rs", "")
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- c = { path = "../c" }
- "#)
- .file("b/src/lib.rs", "")
- .file("c/Cargo.toml", r#"
- [package]
- name = "c"
- version = "0.0.1"
- authors = []
- "#)
- .file("c/src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0));
- assert_that(p.cargo("test").arg("--no-run"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] c v0.0.1 ([..])
-[COMPILING] b v0.0.1 ([..])
-[COMPILING] foo v0.0.1 ([..])
-"));
-}
-
-#[test]
-fn rerun_if_changed_in_dep() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- a = { path = "a" }
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- "#)
- .file("a/build.rs", r#"
- fn main() {
- println!("cargo:rerun-if-changed=build.rs");
- }
- "#)
- .file("a/src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0));
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stdout(""));
-}
-
-#[test]
-fn same_build_dir_cached_packages() {
- let p = project("foo")
- .file("a1/Cargo.toml", r#"
- [package]
- name = "a1"
- version = "0.0.1"
- authors = []
- [dependencies]
- b = { path = "../b" }
- "#)
- .file("a1/src/lib.rs", "")
- .file("a2/Cargo.toml", r#"
- [package]
- name = "a2"
- version = "0.0.1"
- authors = []
- [dependencies]
- b = { path = "../b" }
- "#)
- .file("a2/src/lib.rs", "")
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.0.1"
- authors = []
- [dependencies]
- c = { path = "../c" }
- "#)
- .file("b/src/lib.rs", "")
- .file("c/Cargo.toml", r#"
- [package]
- name = "c"
- version = "0.0.1"
- authors = []
- [dependencies]
- d = { path = "../d" }
- "#)
- .file("c/src/lib.rs", "")
- .file("d/Cargo.toml", r#"
- [package]
- name = "d"
- version = "0.0.1"
- authors = []
- "#)
- .file("d/src/lib.rs", "")
- .file(".cargo/config", r#"
- [build]
- target-dir = "./target"
- "#);
- p.build();
-
- assert_that(p.cargo("build").cwd(p.root().join("a1")),
- execs().with_status(0).with_stderr(&format!("\
-[COMPILING] d v0.0.1 ({dir}/d)
-[COMPILING] c v0.0.1 ({dir}/c)
-[COMPILING] b v0.0.1 ({dir}/b)
-[COMPILING] a1 v0.0.1 ({dir}/a1)
-", dir = p.url())));
- assert_that(p.cargo("build").cwd(p.root().join("a2")),
- execs().with_status(0).with_stderr(&format!("\
-[COMPILING] a2 v0.0.1 ({dir}/a2)
-", dir = p.url())));
-}
+++ /dev/null
-use std::fs::{self, File};
-use std::io::prelude::*;
-
-use support::{project, execs};
-use hamcrest::{assert_that, existing_file, is_not};
-
-#[test]
-fn adding_and_removing_packages() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- authors = []
- version = "0.0.1"
- "#)
- .file("bar/src/lib.rs", "");
-
- assert_that(p.cargo_process("generate-lockfile"),
- execs().with_status(0));
-
- let lockfile = p.root().join("Cargo.lock");
- let toml = p.root().join("Cargo.toml");
- let mut lock1 = String::new();
- File::open(&lockfile).unwrap().read_to_string(&mut lock1).unwrap();
-
- // add a dep
- File::create(&toml).unwrap().write_all(br#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
-
- [dependencies.bar]
- path = "bar"
- "#).unwrap();
- assert_that(p.cargo("generate-lockfile"),
- execs().with_status(0));
- let mut lock2 = String::new();
- File::open(&lockfile).unwrap().read_to_string(&mut lock2).unwrap();
- assert!(lock1 != lock2);
-
- // change the dep
- File::create(&p.root().join("bar/Cargo.toml")).unwrap().write_all(br#"
- [package]
- name = "bar"
- authors = []
- version = "0.0.2"
- "#).unwrap();
- assert_that(p.cargo("generate-lockfile"),
- execs().with_status(0));
- let mut lock3 = String::new();
- File::open(&lockfile).unwrap().read_to_string(&mut lock3).unwrap();
- assert!(lock1 != lock3);
- assert!(lock2 != lock3);
-
- // remove the dep
- println!("lock4");
- File::create(&toml).unwrap().write_all(br#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
- "#).unwrap();
- assert_that(p.cargo("generate-lockfile"),
- execs().with_status(0));
- let mut lock4 = String::new();
- File::open(&lockfile).unwrap().read_to_string(&mut lock4).unwrap();
- assert_eq!(lock1, lock4);
-}
-
-#[test]
-fn preserve_metadata() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- authors = []
- version = "0.0.1"
- "#)
- .file("bar/src/lib.rs", "");
-
- assert_that(p.cargo_process("generate-lockfile"),
- execs().with_status(0));
-
- let metadata = r#"
-[metadata]
-bar = "baz"
-foo = "bar"
-"#;
- let lockfile = p.root().join("Cargo.lock");
- {
- let mut lock = String::new();
- File::open(&lockfile).unwrap().read_to_string(&mut lock).unwrap();
- let data = lock + metadata;
- File::create(&lockfile).unwrap().write_all(data.as_bytes()).unwrap();
- }
-
- // Build and make sure the metadata is still there
- assert_that(p.cargo("build"),
- execs().with_status(0));
- let mut lock = String::new();
- File::open(&lockfile).unwrap().read_to_string(&mut lock).unwrap();
- assert!(lock.contains(metadata.trim()), "{}", lock);
-
- // Update and make sure the metadata is still there
- assert_that(p.cargo("update"),
- execs().with_status(0));
- let mut lock = String::new();
- File::open(&lockfile).unwrap().read_to_string(&mut lock).unwrap();
- assert!(lock.contains(metadata.trim()), "{}", lock);
-}
-
-#[test]
-fn preserve_line_endings_issue_2076() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- authors = []
- version = "0.0.1"
- "#)
- .file("bar/src/lib.rs", "");
-
- let lockfile = p.root().join("Cargo.lock");
- assert_that(p.cargo_process("generate-lockfile"),
- execs().with_status(0));
- assert_that(&lockfile,
- existing_file());
- assert_that(p.cargo("generate-lockfile"),
- execs().with_status(0));
-
- let mut lock0 = String::new();
- {
- File::open(&lockfile).unwrap().read_to_string(&mut lock0).unwrap();
- }
-
- assert!(lock0.starts_with("[root]\n"));
-
- let lock1 = lock0.replace("\n", "\r\n");
- {
- File::create(&lockfile).unwrap().write_all(lock1.as_bytes()).unwrap();
- }
-
- assert_that(p.cargo("generate-lockfile"),
- execs().with_status(0));
-
- let mut lock2 = String::new();
- {
- File::open(&lockfile).unwrap().read_to_string(&mut lock2).unwrap();
- }
-
- assert!(lock2.starts_with("[root]\r\n"));
- assert_eq!(lock1, lock2);
-}
-
-#[test]
-fn cargo_update_generate_lockfile() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.0.1"
- "#)
- .file("src/main.rs", "fn main() {}");
-
- let lockfile = p.root().join("Cargo.lock");
- assert_that(&lockfile, is_not(existing_file()));
- assert_that(p.cargo_process("update"), execs().with_status(0).with_stdout(""));
- assert_that(&lockfile, existing_file());
-
- fs::remove_file(p.root().join("Cargo.lock")).unwrap();
-
- assert_that(&lockfile, is_not(existing_file()));
- assert_that(p.cargo("update"), execs().with_status(0).with_stdout(""));
- assert_that(&lockfile, existing_file());
-
-}
+++ /dev/null
-use std::fs::{self, File};
-use std::io::prelude::*;
-use std::env;
-use tempdir::TempDir;
-use support::{execs, paths, cargo_dir};
-use hamcrest::{assert_that, existing_file, existing_dir, is_not};
-
-use cargo::util::{process, ProcessBuilder};
-
-fn cargo_process(s: &str) -> ProcessBuilder {
- let mut p = process(&cargo_dir().join("cargo"));
- p.arg(s).cwd(&paths::root()).env("HOME", &paths::home());
- return p;
-}
-
-#[test]
-fn simple_lib() {
- assert_that(cargo_process("init").arg("--vcs").arg("none")
- .env("USER", "foo"),
- execs().with_status(0));
-
- assert_that(&paths::root().join("Cargo.toml"), existing_file());
- assert_that(&paths::root().join("src/lib.rs"), existing_file());
- assert_that(&paths::root().join(".gitignore"), is_not(existing_file()));
-
- assert_that(cargo_process("build"),
- execs().with_status(0));
-}
-
-#[test]
-fn simple_bin() {
- let path = paths::root().join("foo");
- fs::create_dir(&path).unwrap();
- assert_that(cargo_process("init").arg("--bin").arg("--vcs").arg("none")
- .env("USER", "foo").cwd(&path),
- execs().with_status(0));
-
- assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
- assert_that(&paths::root().join("foo/src/main.rs"), existing_file());
-
- assert_that(cargo_process("build").cwd(&path),
- execs().with_status(0));
- assert_that(&paths::root().join(&format!("foo/target/debug/foo{}",
- env::consts::EXE_SUFFIX)),
- existing_file());
-}
-
-fn bin_already_exists(explicit: bool, rellocation: &str) {
- let path = paths::root().join("foo");
- fs::create_dir_all(&path.join("src")).unwrap();
-
- let sourcefile_path = path.join(rellocation);
-
- let content = br#"
- fn main() {
- println!("Hello, world 2!");
- }
- "#;
-
- File::create(&sourcefile_path).unwrap().write_all(content).unwrap();
-
- if explicit {
- assert_that(cargo_process("init").arg("--bin").arg("--vcs").arg("none")
- .env("USER", "foo").cwd(&path),
- execs().with_status(0));
- } else {
- assert_that(cargo_process("init").arg("--vcs").arg("none")
- .env("USER", "foo").cwd(&path),
- execs().with_status(0));
- }
-
- assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
- assert_that(&paths::root().join("foo/src/lib.rs"), is_not(existing_file()));
-
- // Check that our file is not overwritten
- let mut new_content = Vec::new();
- File::open(&sourcefile_path).unwrap().read_to_end(&mut new_content).unwrap();
- assert_eq!(Vec::from(content as &[u8]), new_content);
-}
-
-#[test]
-fn bin_already_exists_explicit() {
- bin_already_exists(true, "src/main.rs")
-}
-
-#[test]
-fn bin_already_exists_implicit() {
- bin_already_exists(false, "src/main.rs")
-}
-
-#[test]
-fn bin_already_exists_explicit_nosrc() {
- bin_already_exists(true, "main.rs")
-}
-
-#[test]
-fn bin_already_exists_implicit_nosrc() {
- bin_already_exists(false, "main.rs")
-}
-
-#[test]
-fn bin_already_exists_implicit_namenosrc() {
- bin_already_exists(false, "foo.rs")
-}
-
-#[test]
-fn bin_already_exists_implicit_namesrc() {
- bin_already_exists(false, "src/foo.rs")
-}
-
-#[test]
-fn confused_by_multiple_lib_files() {
- let path = paths::root().join("foo");
- fs::create_dir_all(&path.join("src")).unwrap();
-
- let sourcefile_path1 = path.join("src/lib.rs");
-
- File::create(&sourcefile_path1).unwrap().write_all(br#"
- fn qqq () {
- println!("Hello, world 2!");
- }
- "#).unwrap();
-
- let sourcefile_path2 = path.join("lib.rs");
-
- File::create(&sourcefile_path2).unwrap().write_all(br#"
- fn qqq () {
- println!("Hello, world 3!");
- }
- "#).unwrap();
-
- assert_that(cargo_process("init").arg("--vcs").arg("none")
- .env("USER", "foo").cwd(&path),
- execs().with_status(101).with_stderr("\
-[ERROR] cannot have a project with multiple libraries, found both `src/lib.rs` and `lib.rs`
-"));
-
- assert_that(&paths::root().join("foo/Cargo.toml"), is_not(existing_file()));
-}
-
-
-#[test]
-fn multibin_project_name_clash() {
- let path = paths::root().join("foo");
- fs::create_dir(&path).unwrap();
-
- let sourcefile_path1 = path.join("foo.rs");
-
- File::create(&sourcefile_path1).unwrap().write_all(br#"
- fn main () {
- println!("Hello, world 2!");
- }
- "#).unwrap();
-
- let sourcefile_path2 = path.join("main.rs");
-
- File::create(&sourcefile_path2).unwrap().write_all(br#"
- fn main () {
- println!("Hello, world 3!");
- }
- "#).unwrap();
-
- assert_that(cargo_process("init").arg("--vcs").arg("none")
- .env("USER", "foo").cwd(&path),
- execs().with_status(101).with_stderr("\
-[ERROR] multiple possible binary sources found:
- main.rs
- foo.rs
-cannot automatically generate Cargo.toml as the main target would be ambiguous
-"));
-
- assert_that(&paths::root().join("foo/Cargo.toml"), is_not(existing_file()));
-}
-
-fn lib_already_exists(rellocation: &str) {
- let path = paths::root().join("foo");
- fs::create_dir_all(&path.join("src")).unwrap();
-
- let sourcefile_path = path.join(rellocation);
-
- let content = br#"
- pub fn qqq() {}
- "#;
-
- File::create(&sourcefile_path).unwrap().write_all(content).unwrap();
-
- assert_that(cargo_process("init").arg("--vcs").arg("none")
- .env("USER", "foo").cwd(&path),
- execs().with_status(0));
-
- assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
- assert_that(&paths::root().join("foo/src/main.rs"), is_not(existing_file()));
-
- // Check that our file is not overwritten
- let mut new_content = Vec::new();
- File::open(&sourcefile_path).unwrap().read_to_end(&mut new_content).unwrap();
- assert_eq!(Vec::from(content as &[u8]), new_content);
-}
-
-#[test]
-fn lib_already_exists_src() {
- lib_already_exists("src/lib.rs")
-}
-
-#[test]
-fn lib_already_exists_nosrc() {
- lib_already_exists("lib.rs")
-}
-
-#[test]
-fn simple_git() {
- assert_that(cargo_process("init").arg("--vcs").arg("git")
- .env("USER", "foo"),
- execs().with_status(0));
-
- assert_that(&paths::root().join("Cargo.toml"), existing_file());
- assert_that(&paths::root().join("src/lib.rs"), existing_file());
- assert_that(&paths::root().join(".git"), existing_dir());
- assert_that(&paths::root().join(".gitignore"), existing_file());
-}
-
-#[test]
-fn auto_git() {
- let td = TempDir::new("cargo").unwrap();
- let foo = &td.path().join("foo");
- fs::create_dir_all(&foo).unwrap();
- assert_that(cargo_process("init").cwd(foo.clone())
- .env("USER", "foo"),
- execs().with_status(0));
-
- assert_that(&foo.join("Cargo.toml"), existing_file());
- assert_that(&foo.join("src/lib.rs"), existing_file());
- assert_that(&foo.join(".git"), existing_dir());
- assert_that(&foo.join(".gitignore"), existing_file());
-}
-
-#[test]
-fn invalid_dir_name() {
- let foo = &paths::root().join("foo.bar");
- fs::create_dir_all(&foo).unwrap();
- assert_that(cargo_process("init").cwd(foo.clone())
- .env("USER", "foo"),
- execs().with_status(101).with_stderr("\
-[ERROR] Invalid character `.` in crate name: `foo.bar`
-use --name to override crate name
-"));
-
- assert_that(&foo.join("Cargo.toml"), is_not(existing_file()));
-}
-
-#[test]
-fn reserved_name() {
- let test = &paths::root().join("test");
- fs::create_dir_all(&test).unwrap();
- assert_that(cargo_process("init").cwd(test.clone())
- .env("USER", "foo"),
- execs().with_status(101).with_stderr("\
-[ERROR] The name `test` cannot be used as a crate name\n\
-use --name to override crate name
-"));
-
- assert_that(&test.join("Cargo.toml"), is_not(existing_file()));
-}
-
-#[test]
-fn git_autodetect() {
- fs::create_dir(&paths::root().join(".git")).unwrap();
-
- assert_that(cargo_process("init")
- .env("USER", "foo"),
- execs().with_status(0));
-
-
- assert_that(&paths::root().join("Cargo.toml"), existing_file());
- assert_that(&paths::root().join("src/lib.rs"), existing_file());
- assert_that(&paths::root().join(".git"), existing_dir());
- assert_that(&paths::root().join(".gitignore"), existing_file());
-}
-
-
-#[test]
-fn mercurial_autodetect() {
- fs::create_dir(&paths::root().join(".hg")).unwrap();
-
- assert_that(cargo_process("init")
- .env("USER", "foo"),
- execs().with_status(0));
-
-
- assert_that(&paths::root().join("Cargo.toml"), existing_file());
- assert_that(&paths::root().join("src/lib.rs"), existing_file());
- assert_that(&paths::root().join(".git"), is_not(existing_dir()));
- assert_that(&paths::root().join(".hgignore"), existing_file());
-}
-
-#[test]
-fn gitignore_appended_not_replaced() {
- fs::create_dir(&paths::root().join(".git")).unwrap();
-
- File::create(&paths::root().join(".gitignore")).unwrap().write_all(b"qqqqqq\n").unwrap();
-
- assert_that(cargo_process("init")
- .env("USER", "foo"),
- execs().with_status(0));
-
-
- assert_that(&paths::root().join("Cargo.toml"), existing_file());
- assert_that(&paths::root().join("src/lib.rs"), existing_file());
- assert_that(&paths::root().join(".git"), existing_dir());
- assert_that(&paths::root().join(".gitignore"), existing_file());
-
- let mut contents = String::new();
- File::open(&paths::root().join(".gitignore")).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"qqqqqq"#));
-}
-
-#[test]
-fn cargo_lock_gitignored_if_lib1() {
- fs::create_dir(&paths::root().join(".git")).unwrap();
-
- assert_that(cargo_process("init").arg("--vcs").arg("git")
- .env("USER", "foo"),
- execs().with_status(0));
-
- assert_that(&paths::root().join(".gitignore"), existing_file());
-
- let mut contents = String::new();
- File::open(&paths::root().join(".gitignore")).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"Cargo.lock"#));
-}
-
-#[test]
-fn cargo_lock_gitignored_if_lib2() {
- fs::create_dir(&paths::root().join(".git")).unwrap();
-
- File::create(&paths::root().join("lib.rs")).unwrap().write_all(br#""#).unwrap();
-
- assert_that(cargo_process("init").arg("--vcs").arg("git")
- .env("USER", "foo"),
- execs().with_status(0));
-
- assert_that(&paths::root().join(".gitignore"), existing_file());
-
- let mut contents = String::new();
- File::open(&paths::root().join(".gitignore")).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"Cargo.lock"#));
-}
-
-#[test]
-fn cargo_lock_not_gitignored_if_bin1() {
- fs::create_dir(&paths::root().join(".git")).unwrap();
-
- assert_that(cargo_process("init").arg("--vcs").arg("git")
- .arg("--bin")
- .env("USER", "foo"),
- execs().with_status(0));
-
- assert_that(&paths::root().join(".gitignore"), existing_file());
-
- let mut contents = String::new();
- File::open(&paths::root().join(".gitignore")).unwrap().read_to_string(&mut contents).unwrap();
- assert!(!contents.contains(r#"Cargo.lock"#));
-}
-
-#[test]
-fn cargo_lock_not_gitignored_if_bin2() {
- fs::create_dir(&paths::root().join(".git")).unwrap();
-
- File::create(&paths::root().join("main.rs")).unwrap().write_all(br#""#).unwrap();
-
- assert_that(cargo_process("init").arg("--vcs").arg("git")
- .env("USER", "foo"),
- execs().with_status(0));
-
- assert_that(&paths::root().join(".gitignore"), existing_file());
-
- let mut contents = String::new();
- File::open(&paths::root().join(".gitignore")).unwrap().read_to_string(&mut contents).unwrap();
- assert!(!contents.contains(r#"Cargo.lock"#));
-}
-
-#[test]
-fn with_argument() {
- assert_that(cargo_process("init").arg("foo").arg("--vcs").arg("none")
- .env("USER", "foo"),
- execs().with_status(0));
- assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
-}
-
-
-#[test]
-fn unknown_flags() {
- assert_that(cargo_process("init").arg("foo").arg("--flag"),
- execs().with_status(1)
- .with_stderr("\
-[ERROR] Unknown flag: '--flag'
-
-Usage:
- cargo init [options] [<path>]
- cargo init -h | --help
-"));
-}
-
-#[cfg(not(windows))]
-#[test]
-fn no_filename() {
- assert_that(cargo_process("init").arg("/"),
- execs().with_status(101)
- .with_stderr(&format!("\
-[ERROR] cannot auto-detect project name from path \"/\" ; use --name to override
-")));
-}
+++ /dev/null
-use std::fmt;
-use std::fs::{self, File};
-use std::io::prelude::*;
-use std::path::{Path, PathBuf};
-use support::paths::CargoPathExt;
-
-use cargo::util::ProcessBuilder;
-use hamcrest::{assert_that, existing_file, is_not, Matcher, MatchResult};
-
-use support::{project, execs};
-use support::paths;
-use support::registry::Package;
-use support::git;
-
-pub use self::InstalledExe as has_installed_exe;
-
-fn cargo_process(s: &str) -> ProcessBuilder {
- let mut p = ::cargo_process();
- p.arg(s);
- return p
-}
-
-fn pkg(name: &str, vers: &str) {
- Package::new(name, vers)
- .file("src/lib.rs", "")
- .file("src/main.rs", &format!("
- extern crate {};
- fn main() {{}}
- ", name))
- .publish()
-}
-
-fn exe(name: &str) -> String {
- if cfg!(windows) {format!("{}.exe", name)} else {name.to_string()}
-}
-
-pub fn cargo_home() -> PathBuf {
- paths::home().join(".cargo")
-}
-
-pub struct InstalledExe(pub &'static str);
-
-impl<P: AsRef<Path>> Matcher<P> for InstalledExe {
- fn matches(&self, path: P) -> MatchResult {
- let path = path.as_ref().join("bin").join(exe(self.0));
- existing_file().matches(&path)
- }
-}
-
-impl fmt::Display for InstalledExe {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "installed exe `{}`", self.0)
- }
-}
-
-#[test]
-fn simple() {
- pkg("foo", "0.0.1");
-
- assert_that(cargo_process("install").arg("foo"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] registry `[..]`
-[DOWNLOADING] foo v0.0.1 (registry file://[..])
-[COMPILING] foo v0.0.1 (registry file://[..])
-[INSTALLING] {home}[..]bin[..]foo[..]
-warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
-",
- home = cargo_home().display())));
- assert_that(cargo_home(), has_installed_exe("foo"));
-
- assert_that(cargo_process("uninstall").arg("foo"),
- execs().with_status(0).with_stderr(&format!("\
-[REMOVING] {home}[..]bin[..]foo[..]
-",
- home = cargo_home().display())));
- assert_that(cargo_home(), is_not(has_installed_exe("foo")));
-}
-
-#[test]
-fn pick_max_version() {
- pkg("foo", "0.0.1");
- pkg("foo", "0.0.2");
-
- assert_that(cargo_process("install").arg("foo"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] registry `[..]`
-[DOWNLOADING] foo v0.0.2 (registry file://[..])
-[COMPILING] foo v0.0.2 (registry file://[..])
-[INSTALLING] {home}[..]bin[..]foo[..]
-warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
-",
- home = cargo_home().display())));
- assert_that(cargo_home(), has_installed_exe("foo"));
-}
-
-#[test]
-fn missing() {
- pkg("foo", "0.0.1");
- assert_that(cargo_process("install").arg("bar"),
- execs().with_status(101).with_stderr("\
-[UPDATING] registry [..]
-[ERROR] could not find `bar` in `registry file://[..]`
-"));
-}
-
-#[test]
-fn bad_version() {
- pkg("foo", "0.0.1");
- assert_that(cargo_process("install").arg("foo").arg("--vers=0.2.0"),
- execs().with_status(101).with_stderr("\
-[UPDATING] registry [..]
-[ERROR] could not find `foo` in `registry file://[..]` with version `0.2.0`
-"));
-}
-
-#[test]
-fn no_crate() {
- assert_that(cargo_process("install"),
- execs().with_status(101).with_stderr("\
-[ERROR] `[..]` is not a crate root; specify a crate to install [..]
-
-Caused by:
- failed to read `[..]Cargo.toml`
-
-Caused by:
- [..] (os error [..])
-"));
-}
-
-#[test]
-fn install_location_precedence() {
- pkg("foo", "0.0.1");
-
- let root = paths::root();
- let t1 = root.join("t1");
- let t2 = root.join("t2");
- let t3 = root.join("t3");
- let t4 = cargo_home();
-
- fs::create_dir(root.join(".cargo")).unwrap();
- File::create(root.join(".cargo/config")).unwrap().write_all(format!("\
- [install]
- root = '{}'
- ", t3.display()).as_bytes()).unwrap();
-
- println!("install --root");
-
- assert_that(cargo_process("install").arg("foo")
- .arg("--root").arg(&t1)
- .env("CARGO_INSTALL_ROOT", &t2),
- execs().with_status(0));
- assert_that(&t1, has_installed_exe("foo"));
- assert_that(&t2, is_not(has_installed_exe("foo")));
-
- println!("install CARGO_INSTALL_ROOT");
-
- assert_that(cargo_process("install").arg("foo")
- .env("CARGO_INSTALL_ROOT", &t2),
- execs().with_status(0));
- assert_that(&t2, has_installed_exe("foo"));
- assert_that(&t3, is_not(has_installed_exe("foo")));
-
- println!("install install.root");
-
- assert_that(cargo_process("install").arg("foo"),
- execs().with_status(0));
- assert_that(&t3, has_installed_exe("foo"));
- assert_that(&t4, is_not(has_installed_exe("foo")));
-
- fs::remove_file(root.join(".cargo/config")).unwrap();
-
- println!("install cargo home");
-
- assert_that(cargo_process("install").arg("foo"),
- execs().with_status(0));
- assert_that(&t4, has_installed_exe("foo"));
-}
-
-#[test]
-fn install_path() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--path").arg(p.root()),
- execs().with_status(0));
- assert_that(cargo_home(), has_installed_exe("foo"));
- assert_that(cargo_process("install").arg("--path").arg(".").cwd(p.root()),
- execs().with_status(101).with_stderr("\
-[ERROR] binary `foo[..]` already exists in destination as part of `foo v0.1.0 [..]`
-Add --force to overwrite
-"));
-}
-
-#[test]
-fn multiple_crates_error() {
- let p = git::repo(&paths::root().join("foo"))
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("a/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.1.0"
- authors = []
- "#)
- .file("a/src/main.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--git").arg(p.url().to_string()),
- execs().with_status(101).with_stderr("\
-[UPDATING] git repository [..]
-[ERROR] multiple packages with binaries found: bar, foo
-"));
-}
-
-#[test]
-fn multiple_crates_select() {
- let p = git::repo(&paths::root().join("foo"))
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("a/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.1.0"
- authors = []
- "#)
- .file("a/src/main.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--git").arg(p.url().to_string())
- .arg("foo"),
- execs().with_status(0));
- assert_that(cargo_home(), has_installed_exe("foo"));
- assert_that(cargo_home(), is_not(has_installed_exe("bar")));
-
- assert_that(cargo_process("install").arg("--git").arg(p.url().to_string())
- .arg("bar"),
- execs().with_status(0));
- assert_that(cargo_home(), has_installed_exe("bar"));
-}
-
-#[test]
-fn multiple_crates_auto_binaries() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
-
- [dependencies]
- bar = { path = "a" }
- "#)
- .file("src/main.rs", "extern crate bar; fn main() {}")
- .file("a/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.1.0"
- authors = []
- "#)
- .file("a/src/lib.rs", "");
- p.build();
-
- assert_that(cargo_process("install").arg("--path").arg(p.root()),
- execs().with_status(0));
- assert_that(cargo_home(), has_installed_exe("foo"));
-}
-
-#[test]
-fn multiple_crates_auto_examples() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
-
- [dependencies]
- bar = { path = "a" }
- "#)
- .file("src/lib.rs", "extern crate bar;")
- .file("examples/foo.rs", "
- extern crate bar;
- extern crate foo;
- fn main() {}
- ")
- .file("a/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.1.0"
- authors = []
- "#)
- .file("a/src/lib.rs", "");
- p.build();
-
- assert_that(cargo_process("install").arg("--path").arg(p.root())
- .arg("--example=foo"),
- execs().with_status(0));
- assert_that(cargo_home(), has_installed_exe("foo"));
-}
-
-#[test]
-fn no_binaries_or_examples() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
-
- [dependencies]
- bar = { path = "a" }
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.1.0"
- authors = []
- "#)
- .file("a/src/lib.rs", "");
- p.build();
-
- assert_that(cargo_process("install").arg("--path").arg(p.root()),
- execs().with_status(101).with_stderr("\
-[ERROR] no packages found with binaries or examples
-"));
-}
-
-#[test]
-fn no_binaries() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file("examples/foo.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--path").arg(p.root()).arg("foo"),
- execs().with_status(101).with_stderr("\
-[ERROR] specified package has no binaries
-"));
-}
-
-#[test]
-fn examples() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file("examples/foo.rs", "extern crate foo; fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--path").arg(p.root())
- .arg("--example=foo"),
- execs().with_status(0));
- assert_that(cargo_home(), has_installed_exe("foo"));
-}
-
-#[test]
-fn install_twice() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/bin/foo-bin1.rs", "fn main() {}")
- .file("src/bin/foo-bin2.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--path").arg(p.root()),
- execs().with_status(0));
- assert_that(cargo_process("install").arg("--path").arg(p.root()),
- execs().with_status(101).with_stderr("\
-[ERROR] binary `foo-bin1[..]` already exists in destination as part of `foo v0.1.0 ([..])`
-binary `foo-bin2[..]` already exists in destination as part of `foo v0.1.0 ([..])`
-Add --force to overwrite
-"));
-}
-
-#[test]
-fn install_force() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--path").arg(p.root()),
- execs().with_status(0));
-
- let p = project("foo2")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.2.0"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--force").arg("--path").arg(p.root()),
- execs().with_status(0).with_stderr(&format!("\
-[COMPILING] foo v0.2.0 ([..])
-[REPLACING] {home}[..]bin[..]foo[..]
-warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
-",
- home = cargo_home().display())));
-
- assert_that(cargo_process("install").arg("--list"),
- execs().with_status(0).with_stdout("\
-foo v0.2.0 ([..]):
- foo[..]
-"));
-}
-
-#[test]
-fn install_force_partial_overlap() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/bin/foo-bin1.rs", "fn main() {}")
- .file("src/bin/foo-bin2.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--path").arg(p.root()),
- execs().with_status(0));
-
- let p = project("foo2")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.2.0"
- authors = []
- "#)
- .file("src/bin/foo-bin2.rs", "fn main() {}")
- .file("src/bin/foo-bin3.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--force").arg("--path").arg(p.root()),
- execs().with_status(0).with_stderr(&format!("\
-[COMPILING] foo v0.2.0 ([..])
-[INSTALLING] {home}[..]bin[..]foo-bin3[..]
-[REPLACING] {home}[..]bin[..]foo-bin2[..]
-warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
-",
- home = cargo_home().display())));
-
- assert_that(cargo_process("install").arg("--list"),
- execs().with_status(0).with_stdout("\
-foo v0.1.0 ([..]):
- foo-bin1[..]
-foo v0.2.0 ([..]):
- foo-bin2[..]
- foo-bin3[..]
-"));
-}
-
-#[test]
-fn install_force_bin() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/bin/foo-bin1.rs", "fn main() {}")
- .file("src/bin/foo-bin2.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--path").arg(p.root()),
- execs().with_status(0));
-
- let p = project("foo2")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.2.0"
- authors = []
- "#)
- .file("src/bin/foo-bin1.rs", "fn main() {}")
- .file("src/bin/foo-bin2.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--force")
- .arg("--bin")
- .arg("foo-bin2")
- .arg("--path")
- .arg(p.root()),
- execs().with_status(0).with_stderr(&format!("\
-[COMPILING] foo v0.2.0 ([..])
-[REPLACING] {home}[..]bin[..]foo-bin2[..]
-warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
-",
- home = cargo_home().display())));
-
- assert_that(cargo_process("install").arg("--list"),
- execs().with_status(0).with_stdout("\
-foo v0.1.0 ([..]):
- foo-bin1[..]
-foo v0.2.0 ([..]):
- foo-bin2[..]
-"));
-}
-
-#[test]
-fn compile_failure() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/main.rs", "");
- p.build();
-
- assert_that(cargo_process("install").arg("--path").arg(p.root()),
- execs().with_status(101).with_stderr("\
-[COMPILING] foo v0.1.0 [..]
-error: main function not found
-error: aborting due to previous error
-[ERROR] failed to compile `foo v0.1.0 (file://[..])`, intermediate artifacts can be \
- found at `[..]target`
-
-Caused by:
- Could not compile `foo`.
-
-To learn more, run the command again with --verbose.
-"));
-}
-
-#[test]
-fn git_repo() {
- let p = git::repo(&paths::root().join("foo"))
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--git").arg(p.url().to_string()),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] git repository `[..]`
-[COMPILING] foo v0.1.0 ([..])
-[INSTALLING] {home}[..]bin[..]foo[..]
-warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
-",
- home = cargo_home().display())));
- assert_that(cargo_home(), has_installed_exe("foo"));
- assert_that(cargo_home(), has_installed_exe("foo"));
-}
-
-#[test]
-fn list() {
- pkg("foo", "0.0.1");
- pkg("bar", "0.2.1");
- pkg("bar", "0.2.2");
-
- assert_that(cargo_process("install").arg("--list"),
- execs().with_status(0).with_stdout(""));
-
- assert_that(cargo_process("install").arg("bar").arg("--vers").arg("=0.2.1"),
- execs().with_status(0));
- assert_that(cargo_process("install").arg("foo"),
- execs().with_status(0));
- assert_that(cargo_process("install").arg("--list"),
- execs().with_status(0).with_stdout("\
-bar v0.2.1 (registry [..]):
- bar[..]
-foo v0.0.1 (registry [..]):
- foo[..]
-"));
-}
-
-#[test]
-fn uninstall_pkg_does_not_exist() {
- assert_that(cargo_process("uninstall").arg("foo"),
- execs().with_status(101).with_stderr("\
-[ERROR] package id specification `foo` matched no packages
-"));
-}
-
-#[test]
-fn uninstall_bin_does_not_exist() {
- pkg("foo", "0.0.1");
-
- assert_that(cargo_process("install").arg("foo"),
- execs().with_status(0));
- assert_that(cargo_process("uninstall").arg("foo").arg("--bin=bar"),
- execs().with_status(101).with_stderr("\
-[ERROR] binary `bar[..]` not installed as part of `foo v0.0.1 ([..])`
-"));
-}
-
-#[test]
-fn uninstall_piecemeal() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/bin/foo.rs", "fn main() {}")
- .file("src/bin/bar.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("--path").arg(p.root()),
- execs().with_status(0));
- assert_that(cargo_home(), has_installed_exe("foo"));
- assert_that(cargo_home(), has_installed_exe("bar"));
-
- assert_that(cargo_process("uninstall").arg("foo").arg("--bin=bar"),
- execs().with_status(0).with_stderr("\
-[REMOVING] [..]bar[..]
-"));
-
- assert_that(cargo_home(), has_installed_exe("foo"));
- assert_that(cargo_home(), is_not(has_installed_exe("bar")));
-
- assert_that(cargo_process("uninstall").arg("foo").arg("--bin=foo"),
- execs().with_status(0).with_stderr("\
-[REMOVING] [..]foo[..]
-"));
- assert_that(cargo_home(), is_not(has_installed_exe("foo")));
-
- assert_that(cargo_process("uninstall").arg("foo"),
- execs().with_status(101).with_stderr("\
-[ERROR] package id specification `foo` matched no packages
-"));
-}
-
-#[test]
-fn subcommand_works_out_of_the_box() {
- Package::new("cargo-foo", "1.0.0")
- .file("src/main.rs", r#"
- fn main() {
- println!("bar");
- }
- "#)
- .publish();
- assert_that(cargo_process("install").arg("cargo-foo"),
- execs().with_status(0));
- assert_that(cargo_process("foo"),
- execs().with_status(0).with_stdout("bar\n"));
- assert_that(cargo_process("--list"),
- execs().with_status(0).with_stdout_contains(" foo\n"));
-}
-
-#[test]
-fn installs_from_cwd_by_default() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").cwd(p.root()),
- execs().with_status(0));
- assert_that(cargo_home(), has_installed_exe("foo"));
-}
-
-#[test]
-fn do_not_rebuilds_on_local_install() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("build").arg("--release"),
- execs().with_status(0));
- assert_that(cargo_process("install").arg("--path").arg(p.root()),
- execs().with_status(0).with_stderr("\
-[INSTALLING] [..]
-warning: be sure to add `[..]` to your PATH to be able to run the installed binaries
-"));
-
- assert!(p.build_dir().c_exists());
- assert!(p.release_bin("foo").c_exists());
- assert_that(cargo_home(), has_installed_exe("foo"));
-}
-
-#[test]
-fn reports_unsuccessful_subcommand_result() {
- Package::new("cargo-fail", "1.0.0")
- .file("src/main.rs", r#"
- fn main() {
- panic!();
- }
- "#)
- .publish();
- assert_that(cargo_process("install").arg("cargo-fail"),
- execs().with_status(0));
- assert_that(cargo_process("--list"),
- execs().with_status(0).with_stdout_contains(" fail\n"));
- assert_that(cargo_process("fail"),
- execs().with_status(101).with_stderr_contains("\
-thread '<main>' panicked at 'explicit panic', [..]
-"));
-}
-
-#[test]
-fn git_with_lockfile() {
- let p = git::repo(&paths::root().join("foo"))
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
-
- [dependencies]
- bar = { path = "bar" }
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.1.0"
- authors = []
- "#)
- .file("bar/src/lib.rs", "fn main() {}")
- .file("Cargo.lock", r#"
- [root]
- name = "foo"
- version = "0.1.0"
- dependencies = [ "b 0.1.0" ]
-
- [[package]]
- name = "bar"
- version = "0.1.0"
- "#);
- p.build();
-
- assert_that(cargo_process("install").arg("--git").arg(p.url().to_string()),
- execs().with_status(0));
-}
-
-#[test]
-fn q_silences_warnings() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- assert_that(cargo_process("install").arg("-q").arg("--path").arg(p.root()),
- execs().with_status(0).with_stderr(""));
-}
-
-#[test]
-fn readonly_dir() {
- pkg("foo", "0.0.1");
-
- let root = paths::root();
- let dir = &root.join("readonly");
- fs::create_dir(root.join("readonly")).unwrap();
- let mut perms = fs::metadata(dir).unwrap().permissions();
- perms.set_readonly(true);
- fs::set_permissions(dir, perms).unwrap();
-
- assert_that(cargo_process("install").arg("foo").cwd(dir),
- execs().with_status(0));
- assert_that(cargo_home(), has_installed_exe("foo"));
-}
+++ /dev/null
-use hamcrest::assert_that;
-use support::registry::Package;
-use support::{project, execs, basic_bin_manifest, main_file};
-
-
-#[test]
-fn cargo_metadata_simple() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"));
-
- assert_that(p.cargo_process("metadata"), execs().with_json(r#"
- {
- "packages": [
- {
- "name": "foo",
- "version": "0.5.0",
- "id": "foo[..]",
- "source": null,
- "dependencies": [],
- "targets": [
- {
- "kind": [
- "bin"
- ],
- "name": "foo",
- "src_path": "src[..]foo.rs"
- }
- ],
- "features": {},
- "manifest_path": "[..]Cargo.toml"
- }
- ],
- "resolve": {
- "nodes": [
- {
- "dependencies": [],
- "id": "foo 0.5.0 (path+file:[..]foo)"
- }
- ],
- "root": "foo 0.5.0 (path+file:[..]foo)"
- },
- "version": 1
- }"#));
-}
-
-
-#[test]
-fn cargo_metadata_with_deps_and_version() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- license = "MIT"
- description = "foo"
-
- [[bin]]
- name = "foo"
-
- [dependencies]
- bar = "*"
- "#);
- Package::new("baz", "0.0.1").publish();
- Package::new("bar", "0.0.1").dep("baz", "0.0.1").publish();
-
- assert_that(p.cargo_process("metadata")
- .arg("-q")
- .arg("--format-version").arg("1"),
- execs().with_json(r#"
- {
- "packages": [
- {
- "dependencies": [],
- "features": {},
- "id": "baz 0.0.1 (registry+file:[..])",
- "manifest_path": "[..]Cargo.toml",
- "name": "baz",
- "source": "registry+file:[..]",
- "targets": [
- {
- "kind": [
- "lib"
- ],
- "name": "baz",
- "src_path": "[..]lib.rs"
- }
- ],
- "version": "0.0.1"
- },
- {
- "dependencies": [
- {
- "features": [],
- "kind": null,
- "name": "baz",
- "optional": false,
- "req": "^0.0.1",
- "source": "registry+file:[..]",
- "target": null,
- "uses_default_features": true
- }
- ],
- "features": {},
- "id": "bar 0.0.1 (registry+file:[..])",
- "manifest_path": "[..]Cargo.toml",
- "name": "bar",
- "source": "registry+file:[..]",
- "targets": [
- {
- "kind": [
- "lib"
- ],
- "name": "bar",
- "src_path": "[..]lib.rs"
- }
- ],
- "version": "0.0.1"
- },
- {
- "dependencies": [
- {
- "features": [],
- "kind": null,
- "name": "bar",
- "optional": false,
- "req": "*",
- "source": "registry+file:[..]",
- "target": null,
- "uses_default_features": true
- }
- ],
- "features": {},
- "id": "foo 0.5.0 (path+file:[..]foo)",
- "manifest_path": "[..]Cargo.toml",
- "name": "foo",
- "source": null,
- "targets": [
- {
- "kind": [
- "bin"
- ],
- "name": "foo",
- "src_path": "[..]foo.rs"
- }
- ],
- "version": "0.5.0"
- }
- ],
- "resolve": {
- "nodes": [
- {
- "dependencies": [
- "bar 0.0.1 (registry+file:[..])"
- ],
- "id": "foo 0.5.0 (path+file:[..]foo)"
- },
- {
- "dependencies": [
- "baz 0.0.1 (registry+file:[..])"
- ],
- "id": "bar 0.0.1 (registry+file:[..])"
- },
- {
- "dependencies": [],
- "id": "baz 0.0.1 (registry+file:[..])"
- }
- ],
- "root": "foo 0.5.0 (path+file:[..]foo)"
- },
- "version": 1
- }"#));
-}
-
-#[test]
-fn cargo_metadata_with_invalid_manifest() {
- let p = project("foo")
- .file("Cargo.toml", "");
-
- assert_that(p.cargo_process("metadata"), execs().with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- no `package` or `project` section found."))
-}
-
-const MANIFEST_OUTPUT: &'static str=
- r#"
-{
- "packages": [{
- "name":"foo",
- "version":"0.5.0",
- "id":"foo[..]0.5.0[..](path+file://[..]/foo)",
- "source":null,
- "dependencies":[],
- "targets":[{
- "kind":["bin"],
- "name":"foo",
- "src_path":"src[..]foo.rs"
- }],
- "features":{},
- "manifest_path":"[..]Cargo.toml"
- }],
- "resolve": null,
- "version": 1
-}"#;
-
-#[test]
-fn cargo_metadata_no_deps_path_to_cargo_toml_relative() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("metadata").arg("--no-deps")
- .arg("--manifest-path").arg("foo/Cargo.toml")
- .cwd(p.root().parent().unwrap()),
- execs().with_status(0)
- .with_json(MANIFEST_OUTPUT));
-}
-
-#[test]
-fn cargo_metadata_no_deps_path_to_cargo_toml_absolute() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("metadata").arg("--no-deps")
- .arg("--manifest-path").arg(p.root().join("Cargo.toml"))
- .cwd(p.root().parent().unwrap()),
- execs().with_status(0)
- .with_json(MANIFEST_OUTPUT));
-}
-
-#[test]
-fn cargo_metadata_no_deps_path_to_cargo_toml_parent_relative() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("metadata").arg("--no-deps")
- .arg("--manifest-path").arg("foo")
- .cwd(p.root().parent().unwrap()),
- execs().with_status(101)
- .with_stderr("[ERROR] the manifest-path must be \
- a path to a Cargo.toml file"));
-}
-
-#[test]
-fn cargo_metadata_no_deps_path_to_cargo_toml_parent_absolute() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("metadata").arg("--no-deps")
- .arg("--manifest-path").arg(p.root())
- .cwd(p.root().parent().unwrap()),
- execs().with_status(101)
- .with_stderr("[ERROR] the manifest-path must be \
- a path to a Cargo.toml file"));
-}
-
-#[test]
-fn cargo_metadata_no_deps_cwd() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("metadata").arg("--no-deps")
- .cwd(p.root()),
- execs().with_status(0)
- .with_json(MANIFEST_OUTPUT));
-}
-
-#[test]
-fn carg_metadata_bad_version() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("metadata").arg("--no-deps")
- .arg("--format-version").arg("2")
- .cwd(p.root()),
- execs().with_status(101)
- .with_stderr("[ERROR] metadata version 2 not supported, only 1 is currently supported"));
-}
+++ /dev/null
-use support::{project, execs};
-use hamcrest::assert_that;
-
-#[test]
-fn net_retry_loads_from_config() {
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- git = "https://127.0.0.1:11/foo/bar"
- "#))
- .file("src/main.rs", "").file(".cargo/config", r#"
- [net]
- retry=1
- [http]
- timeout=1
- "#);
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(101)
- .with_stderr_contains(&format!("[WARNING] spurious network error \
-(1 tries remaining): [2/-1] [..]")));
-}
-
-#[test]
-fn net_retry_git_outputs_warning() {
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- git = "https://127.0.0.1:11/foo/bar"
- "#))
- .file(".cargo/config", r#"
- [http]
- timeout=1
- "#)
- .file("src/main.rs", "");
-
- assert_that(p.cargo_process("build").arg("-v").arg("-j").arg("1"),
- execs().with_status(101)
- .with_stderr_contains(&format!("[WARNING] spurious network error \
-(2 tries remaining): [2/-1] [..]"))
- .with_stderr_contains(&format!("\
-[WARNING] spurious network error (1 tries remaining): [2/-1] [..]")));
-}
+++ /dev/null
-use std::fs::{self, File};
-use std::io::prelude::*;
-use std::env;
-use tempdir::TempDir;
-
-use support::{execs, paths};
-use support::paths::CargoPathExt;
-use hamcrest::{assert_that, existing_file, existing_dir, is_not};
-
-use cargo::util::ProcessBuilder;
-
-fn cargo_process(s: &str) -> ProcessBuilder {
- let mut p = ::cargo_process();
- p.arg(s);
- return p;
-}
-
-#[test]
-fn simple_lib() {
- assert_that(cargo_process("new").arg("foo").arg("--vcs").arg("none")
- .env("USER", "foo"),
- execs().with_status(0));
-
- assert_that(&paths::root().join("foo"), existing_dir());
- assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
- assert_that(&paths::root().join("foo/src/lib.rs"), existing_file());
- assert_that(&paths::root().join("foo/.gitignore"), is_not(existing_file()));
-
- assert_that(cargo_process("build").cwd(&paths::root().join("foo")),
- execs().with_status(0));
-}
-
-#[test]
-fn simple_bin() {
- assert_that(cargo_process("new").arg("foo").arg("--bin")
- .env("USER", "foo"),
- execs().with_status(0));
-
- assert_that(&paths::root().join("foo"), existing_dir());
- assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
- assert_that(&paths::root().join("foo/src/main.rs"), existing_file());
-
- assert_that(cargo_process("build").cwd(&paths::root().join("foo")),
- execs().with_status(0));
- assert_that(&paths::root().join(&format!("foo/target/debug/foo{}",
- env::consts::EXE_SUFFIX)),
- existing_file());
-}
-
-#[test]
-fn simple_git() {
- let td = TempDir::new("cargo").unwrap();
- assert_that(cargo_process("new").arg("foo").cwd(td.path().clone())
- .env("USER", "foo"),
- execs().with_status(0));
-
- assert_that(td.path(), existing_dir());
- assert_that(&td.path().join("foo/Cargo.toml"), existing_file());
- assert_that(&td.path().join("foo/src/lib.rs"), existing_file());
- assert_that(&td.path().join("foo/.git"), existing_dir());
- assert_that(&td.path().join("foo/.gitignore"), existing_file());
-
- assert_that(cargo_process("build").cwd(&td.path().clone().join("foo")),
- execs().with_status(0));
-}
-
-#[test]
-fn no_argument() {
- assert_that(cargo_process("new"),
- execs().with_status(1)
- .with_stderr("\
-[ERROR] Invalid arguments.
-
-Usage:
- cargo new [options] <path>
- cargo new -h | --help
-"));
-}
-
-#[test]
-fn existing() {
- let dst = paths::root().join("foo");
- fs::create_dir(&dst).unwrap();
- assert_that(cargo_process("new").arg("foo"),
- execs().with_status(101)
- .with_stderr(format!("[ERROR] destination `{}` already exists\n",
- dst.display())));
-}
-
-#[test]
-fn invalid_characters() {
- assert_that(cargo_process("new").arg("foo.rs"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] Invalid character `.` in crate name: `foo.rs`
-use --name to override crate name"));
-}
-
-#[test]
-fn reserved_name() {
- assert_that(cargo_process("new").arg("test"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] The name `test` cannot be used as a crate name\n\
-use --name to override crate name"));
-}
-
-#[test]
-fn keyword_name() {
- assert_that(cargo_process("new").arg("pub"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] The name `pub` cannot be used as a crate name\n\
-use --name to override crate name"));
-}
-
-#[test]
-fn rust_prefix_stripped() {
- assert_that(cargo_process("new").arg("rust-foo").env("USER", "foo"),
- execs().with_status(0)
- .with_stdout("note: package will be named `foo`; use --name to override"));
- let toml = paths::root().join("rust-foo/Cargo.toml");
- let mut contents = String::new();
- File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"name = "foo""#));
-}
-
-#[test]
-fn bin_disables_stripping() {
- assert_that(cargo_process("new").arg("rust-foo").arg("--bin").env("USER", "foo"),
- execs().with_status(0));
- let toml = paths::root().join("rust-foo/Cargo.toml");
- let mut contents = String::new();
- File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"name = "rust-foo""#));
-}
-
-#[test]
-fn explicit_name_not_stripped() {
- assert_that(cargo_process("new").arg("foo").arg("--name").arg("rust-bar").env("USER", "foo"),
- execs().with_status(0));
- let toml = paths::root().join("foo/Cargo.toml");
- let mut contents = String::new();
- File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"name = "rust-bar""#));
-}
-
-#[test]
-fn finds_author_user() {
- // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
- // the hierarchy
- let td = TempDir::new("cargo").unwrap();
- assert_that(cargo_process("new").arg("foo").env("USER", "foo")
- .cwd(td.path().clone()),
- execs().with_status(0));
-
- let toml = td.path().join("foo/Cargo.toml");
- let mut contents = String::new();
- File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"authors = ["foo"]"#));
-}
-
-#[test]
-fn finds_author_user_escaped() {
- // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
- // the hierarchy
- let td = TempDir::new("cargo").unwrap();
- assert_that(cargo_process("new").arg("foo").env("USER", "foo \"bar\"")
- .cwd(td.path().clone()),
- execs().with_status(0));
-
- let toml = td.path().join("foo/Cargo.toml");
- let mut contents = String::new();
- File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"authors = ["foo \"bar\""]"#));
-}
-
-#[test]
-fn finds_author_username() {
- // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
- // the hierarchy
- let td = TempDir::new("cargo").unwrap();
- assert_that(cargo_process("new").arg("foo")
- .env_remove("USER")
- .env("USERNAME", "foo")
- .cwd(td.path().clone()),
- execs().with_status(0));
-
- let toml = td.path().join("foo/Cargo.toml");
- let mut contents = String::new();
- File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"authors = ["foo"]"#));
-}
-
-#[test]
-fn finds_author_priority() {
- // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
- // the hierarchy
- let td = TempDir::new("cargo").unwrap();
- assert_that(cargo_process("new").arg("foo")
- .env("USER", "bar2")
- .env("EMAIL", "baz2")
- .env("CARGO_NAME", "bar")
- .env("CARGO_EMAIL", "baz")
- .cwd(td.path().clone()),
- execs().with_status(0));
-
- let toml = td.path().join("foo/Cargo.toml");
- let mut contents = String::new();
- File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
-}
-
-#[test]
-fn finds_author_email() {
- // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
- // the hierarchy
- let td = TempDir::new("cargo").unwrap();
- assert_that(cargo_process("new").arg("foo")
- .env("USER", "bar")
- .env("EMAIL", "baz")
- .cwd(td.path().clone()),
- execs().with_status(0));
-
- let toml = td.path().join("foo/Cargo.toml");
- let mut contents = String::new();
- File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
-}
-
-#[test]
-fn finds_author_git() {
- ::process("git").args(&["config", "--global", "user.name", "bar"])
- .exec().unwrap();
- ::process("git").args(&["config", "--global", "user.email", "baz"])
- .exec().unwrap();
- assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
- execs().with_status(0));
-
- let toml = paths::root().join("foo/Cargo.toml");
- let mut contents = String::new();
- File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
-}
-
-#[test]
-fn finds_git_email() {
- let td = TempDir::new("cargo").unwrap();
- assert_that(cargo_process("new").arg("foo")
- .env("GIT_AUTHOR_NAME", "foo")
- .env("GIT_AUTHOR_EMAIL", "gitfoo")
- .cwd(td.path().clone()),
- execs().with_status(0));
-
- let toml = td.path().join("foo/Cargo.toml");
- let mut contents = String::new();
- File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"authors = ["foo <gitfoo>"]"#), contents);
-}
-
-
-#[test]
-fn finds_git_author() {
- // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
- // the hierarchy
- let td = TempDir::new("cargo").unwrap();
- assert_that(cargo_process("new").arg("foo")
- .env_remove("USER")
- .env("GIT_COMMITTER_NAME", "gitfoo")
- .cwd(td.path().clone()),
- execs().with_status(0));
-
- let toml = td.path().join("foo/Cargo.toml");
- let mut contents = String::new();
- File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"authors = ["gitfoo"]"#));
-}
-
-#[test]
-fn author_prefers_cargo() {
- ::process("git").args(&["config", "--global", "user.name", "foo"])
- .exec().unwrap();
- ::process("git").args(&["config", "--global", "user.email", "bar"])
- .exec().unwrap();
- let root = paths::root();
- fs::create_dir(&root.join(".cargo")).unwrap();
- File::create(&root.join(".cargo/config")).unwrap().write_all(br#"
- [cargo-new]
- name = "new-foo"
- email = "new-bar"
- vcs = "none"
- "#).unwrap();
-
- assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
- execs().with_status(0));
-
- let toml = paths::root().join("foo/Cargo.toml");
- let mut contents = String::new();
- File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
- assert!(contents.contains(r#"authors = ["new-foo <new-bar>"]"#));
- assert!(!root.join("foo/.gitignore").c_exists());
-}
-
-#[test]
-fn git_prefers_command_line() {
- let root = paths::root();
- let td = TempDir::new("cargo").unwrap();
- fs::create_dir(&root.join(".cargo")).unwrap();
- File::create(&root.join(".cargo/config")).unwrap().write_all(br#"
- [cargo-new]
- vcs = "none"
- name = "foo"
- email = "bar"
- "#).unwrap();
-
- assert_that(cargo_process("new").arg("foo").arg("--vcs").arg("git")
- .cwd(td.path())
- .env("USER", "foo"),
- execs().with_status(0));
- assert!(td.path().join("foo/.gitignore").c_exists());
-}
-
-#[test]
-fn subpackage_no_git() {
- assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
- execs().with_status(0));
-
- let subpackage = paths::root().join("foo").join("components");
- fs::create_dir(&subpackage).unwrap();
- assert_that(cargo_process("new").arg("foo/components/subcomponent")
- .env("USER", "foo"),
- execs().with_status(0));
-
- assert_that(&paths::root().join("foo/components/subcomponent/.git"),
- is_not(existing_file()));
- assert_that(&paths::root().join("foo/components/subcomponent/.gitignore"),
- is_not(existing_file()));
-}
-
-#[test]
-fn subpackage_git_with_vcs_arg() {
- assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
- execs().with_status(0));
-
- let subpackage = paths::root().join("foo").join("components");
- fs::create_dir(&subpackage).unwrap();
- assert_that(cargo_process("new").arg("foo/components/subcomponent")
- .arg("--vcs").arg("git")
- .env("USER", "foo"),
- execs().with_status(0));
-
- assert_that(&paths::root().join("foo/components/subcomponent/.git"),
- existing_dir());
- assert_that(&paths::root().join("foo/components/subcomponent/.gitignore"),
- existing_file());
-}
-
-#[test]
-fn unknown_flags() {
- assert_that(cargo_process("new").arg("foo").arg("--flag"),
- execs().with_status(1)
- .with_stderr("\
-[ERROR] Unknown flag: '--flag'
-
-Usage:
- cargo new [..]
- cargo new [..]
-"));
-}
+++ /dev/null
-use hamcrest::assert_that;
-
-use support::registry::{registry, Package};
-use support::{execs, project};
-use support::git;
-use support::paths;
-
-#[test]
-fn override_simple() {
- Package::new("foo", "0.1.0").publish();
-
- let foo = git::repo(&paths::root().join("override"))
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn foo() {}");
- foo.build();
-
- let p = project("local")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- foo = "0.1.0"
-
- [replace]
- "foo:0.1.0" = {{ git = '{}' }}
- "#, foo.url()))
- .file("src/lib.rs", "
- extern crate foo;
- pub fn bar() {
- foo::foo();
- }
- ");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry `file://[..]`
-[UPDATING] git repository `[..]`
-[COMPILING] foo v0.1.0 (file://[..])
-[COMPILING] local v0.0.1 (file://[..])
-"));
-}
-
-#[test]
-fn missing_version() {
- let p = project("local")
- .file("Cargo.toml", r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- foo = "0.1.0"
-
- [replace]
- foo = { git = 'https://example.com' }
- "#)
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-error: failed to parse manifest at `[..]`
-
-Caused by:
- replacements must specify a version to replace, but `foo` does not
-"));
-}
-
-#[test]
-fn different_version() {
- Package::new("foo", "0.2.0").publish();
- Package::new("foo", "0.1.0").publish();
-
- let p = project("local")
- .file("Cargo.toml", r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- foo = "0.1.0"
-
- [replace]
- "foo:0.1.0" = "0.2.0"
- "#)
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-error: failed to parse manifest at `[..]`
-
-Caused by:
- replacements cannot specify a version requirement, but found one for [..]
-"));
-}
-
-#[test]
-fn transitive() {
- Package::new("foo", "0.1.0").publish();
- Package::new("bar", "0.2.0")
- .dep("foo", "0.1.0")
- .file("src/lib.rs", "extern crate foo; fn bar() { foo::foo(); }")
- .publish();
-
- let foo = git::repo(&paths::root().join("override"))
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn foo() {}");
- foo.build();
-
- let p = project("local")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "0.2.0"
-
- [replace]
- "foo:0.1.0" = {{ git = '{}' }}
- "#, foo.url()))
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry `file://[..]`
-[UPDATING] git repository `[..]`
-[DOWNLOADING] bar v0.2.0 (registry [..])
-[COMPILING] foo v0.1.0 (file://[..])
-[COMPILING] bar v0.2.0 (registry [..])
-[COMPILING] local v0.0.1 (file://[..])
-"));
-
- assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
-}
-
-#[test]
-fn persists_across_rebuilds() {
- Package::new("foo", "0.1.0").publish();
-
- let foo = git::repo(&paths::root().join("override"))
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn foo() {}");
- foo.build();
-
- let p = project("local")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- foo = "0.1.0"
-
- [replace]
- "foo:0.1.0" = {{ git = '{}' }}
- "#, foo.url()))
- .file("src/lib.rs", "
- extern crate foo;
- pub fn bar() {
- foo::foo();
- }
- ");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry `file://[..]`
-[UPDATING] git repository `file://[..]`
-[COMPILING] foo v0.1.0 (file://[..])
-[COMPILING] local v0.0.1 (file://[..])
-"));
-
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stdout(""));
-}
-
-#[test]
-fn replace_registry_with_path() {
- Package::new("foo", "0.1.0").publish();
-
- project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn foo() {}")
- .build();
-
- let p = project("local")
- .file("Cargo.toml", r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- foo = "0.1.0"
-
- [replace]
- "foo:0.1.0" = { path = "../foo" }
- "#)
- .file("src/lib.rs", "
- extern crate foo;
- pub fn bar() {
- foo::foo();
- }
- ");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry `file://[..]`
-[COMPILING] foo v0.1.0 (file://[..])
-[COMPILING] local v0.0.1 (file://[..])
-"));
-}
-
-#[test]
-fn use_a_spec_to_select() {
- Package::new("foo", "0.1.1")
- .file("src/lib.rs", "pub fn foo1() {}")
- .publish();
- Package::new("foo", "0.2.0").publish();
- Package::new("bar", "0.1.1")
- .dep("foo", "0.2")
- .file("src/lib.rs", "
- extern crate foo;
- pub fn bar() { foo::foo3(); }
- ")
- .publish();
-
- let foo = git::repo(&paths::root().join("override"))
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.2.0"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn foo3() {}");
- foo.build();
-
- let p = project("local")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "0.1"
- foo = "0.1"
-
- [replace]
- "foo:0.2.0" = {{ git = '{}' }}
- "#, foo.url()))
- .file("src/lib.rs", "
- extern crate foo;
- extern crate bar;
-
- pub fn local() {
- foo::foo1();
- bar::bar();
- }
- ");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry `file://[..]`
-[UPDATING] git repository `[..]`
-[DOWNLOADING] [..]
-[DOWNLOADING] [..]
-[COMPILING] [..]
-[COMPILING] [..]
-[COMPILING] [..]
-[COMPILING] local v0.0.1 (file://[..])
-"));
-}
-
-#[test]
-fn override_adds_some_deps() {
- Package::new("foo", "0.1.1").publish();
- Package::new("bar", "0.1.0").publish();
-
- let foo = git::repo(&paths::root().join("override"))
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.1.0"
- authors = []
-
- [dependencies]
- foo = "0.1"
- "#)
- .file("src/lib.rs", "");
- foo.build();
-
- let p = project("local")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "0.1"
-
- [replace]
- "bar:0.1.0" = {{ git = '{}' }}
- "#, foo.url()))
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry `file://[..]`
-[UPDATING] git repository `[..]`
-[DOWNLOADING] foo v0.1.1 (registry [..])
-[COMPILING] foo v0.1.1 (registry [..])
-[COMPILING] bar v0.1.0 ([..])
-[COMPILING] local v0.0.1 (file://[..])
-"));
-
- assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
-
- Package::new("foo", "0.1.2").publish();
- assert_that(p.cargo("update").arg("-p").arg(&format!("{}#bar", foo.url())),
- execs().with_status(0).with_stderr("\
-[UPDATING] git repository `file://[..]`
-"));
- assert_that(p.cargo("update").arg("-p").arg(&format!("{}#bar", registry())),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry `file://[..]`
-"));
-
- assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
-}
-
-#[test]
-fn locked_means_locked_yes_no_seriously_i_mean_locked() {
- // this in theory exercises #2041
- Package::new("foo", "0.1.0").publish();
- Package::new("foo", "0.2.0").publish();
- Package::new("bar", "0.1.0").publish();
-
- let foo = git::repo(&paths::root().join("override"))
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.1.0"
- authors = []
-
- [dependencies]
- foo = "*"
- "#)
- .file("src/lib.rs", "");
- foo.build();
-
- let p = project("local")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- foo = "0.1"
- bar = "0.1"
-
- [replace]
- "bar:0.1.0" = {{ git = '{}' }}
- "#, foo.url()))
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0));
-
- assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
- assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
-}
-
-#[test]
-fn override_wrong_name() {
- Package::new("foo", "0.1.0").publish();
-
- let foo = git::repo(&paths::root().join("override"))
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/lib.rs", "");
- foo.build();
-
- let p = project("local")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- foo = "0.1"
-
- [replace]
- "foo:0.1.0" = {{ git = '{}' }}
- "#, foo.url()))
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[UPDATING] registry [..]
-[UPDATING] git repository [..]
-error: no matching package for override `foo:0.1.0` found
-location searched: file://[..]
-version required: = 0.1.0
-"));
-}
-
-#[test]
-fn override_with_nothing() {
- Package::new("foo", "0.1.0").publish();
-
- let foo = git::repo(&paths::root().join("override"))
- .file("src/lib.rs", "");
- foo.build();
-
- let p = project("local")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- foo = "0.1"
-
- [replace]
- "foo:0.1.0" = {{ git = '{}' }}
- "#, foo.url()))
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[UPDATING] registry [..]
-[UPDATING] git repository [..]
-error: Unable to update file://[..]
-
-Caused by:
- Could not find Cargo.toml in `[..]`
-"));
-}
-
-#[test]
-fn override_wrong_version() {
- let p = project("local")
- .file("Cargo.toml", r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [replace]
- "foo:0.1.0" = { git = 'https://example.com', version = '0.2.0' }
- "#)
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-error: failed to parse manifest at `[..]`
-
-Caused by:
- replacements cannot specify a version requirement, but found one for `foo:0.1.0`
-"));
-}
-
-#[test]
-fn multiple_specs() {
- Package::new("foo", "0.1.0").publish();
-
- let foo = git::repo(&paths::root().join("override"))
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn foo() {}");
- foo.build();
-
- let p = project("local")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- foo = "0.1.0"
-
- [replace]
- "foo:0.1.0" = {{ git = '{0}' }}
- "{1}#foo:0.1.0" = {{ git = '{0}' }}
- "#, foo.url(), registry()))
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[UPDATING] registry [..]
-[UPDATING] git repository [..]
-error: overlapping replacement specifications found:
-
- * [..]
- * [..]
-
-both specifications match: foo v0.1.0 ([..])
-"));
-}
-
-#[test]
-fn test_override_dep() {
- Package::new("foo", "0.1.0").publish();
-
- let foo = git::repo(&paths::root().join("override"))
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/lib.rs", "pub fn foo() {}");
- foo.build();
-
- let p = project("local")
- .file("Cargo.toml", &format!(r#"
- [package]
- name = "local"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- foo = "0.1.0"
-
- [replace]
- "foo:0.1.0" = {{ git = '{0}' }}
- "#, foo.url()))
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("test").arg("-p").arg("foo"),
- execs().with_status(101)
- .with_stderr_contains("\
-error: There are multiple `foo` packages in your project, and the [..]
-Please re-run this command with [..]
- [..]#foo:0.1.0
- [..]#foo:0.1.0
-"));
-}
+++ /dev/null
-use std::fs::File;
-use std::io::prelude::*;
-use std::path::Path;
-
-use flate2::read::GzDecoder;
-use git2;
-use tar::Archive;
-
-use support::{project, execs, paths, git, path2url};
-use hamcrest::{assert_that, existing_file};
-
-#[test]
-fn simple() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- exclude = ["*.txt"]
- license = "MIT"
- description = "foo"
- "#)
- .file("src/main.rs", r#"
- fn main() { println!("hello"); }
- "#)
- .file("src/bar.txt", ""); // should be ignored when packaging
-
- assert_that(p.cargo_process("package"),
- execs().with_status(0).with_stderr(&format!("\
-[WARNING] manifest has no documentation[..]
-[PACKAGING] foo v0.0.1 ({dir})
-[VERIFYING] foo v0.0.1 ({dir})
-[COMPILING] foo v0.0.1 ({dir}[..])
-",
- dir = p.url())));
- assert_that(&p.root().join("target/package/foo-0.0.1.crate"), existing_file());
- assert_that(p.cargo("package").arg("-l"),
- execs().with_status(0).with_stdout("\
-Cargo.toml
-src[..]main.rs
-"));
- assert_that(p.cargo("package"),
- execs().with_status(0).with_stdout(""));
-
- let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap();
- let mut rdr = GzDecoder::new(f).unwrap();
- let mut contents = Vec::new();
- rdr.read_to_end(&mut contents).unwrap();
- let mut ar = Archive::new(&contents[..]);
- for f in ar.entries().unwrap() {
- let f = f.unwrap();
- let fname = f.header().path_bytes();
- let fname = &*fname;
- assert!(fname == b"foo-0.0.1/Cargo.toml" ||
- fname == b"foo-0.0.1/src/main.rs",
- "unexpected filename: {:?}", f.header().path())
- }
-}
-
-#[test]
-fn metadata_warning() {
- let p = project("all")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#);
- assert_that(p.cargo_process("package"),
- execs().with_status(0).with_stderr(&format!("\
-warning: manifest has no description, license, license-file, documentation, \
-homepage or repository. See \
-http://doc.crates.io/manifest.html#package-metadata for more info.
-[PACKAGING] foo v0.0.1 ({dir})
-[VERIFYING] foo v0.0.1 ({dir})
-[COMPILING] foo v0.0.1 ({dir}[..])
-",
- dir = p.url())));
-
- let p = project("one")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- license = "MIT"
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#);
- assert_that(p.cargo_process("package"),
- execs().with_status(0).with_stderr(&format!("\
-warning: manifest has no description, documentation, homepage or repository. See \
-http://doc.crates.io/manifest.html#package-metadata for more info.
-[PACKAGING] foo v0.0.1 ({dir})
-[VERIFYING] foo v0.0.1 ({dir})
-[COMPILING] foo v0.0.1 ({dir}[..])
-",
- dir = p.url())));
-
- let p = project("all")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- license = "MIT"
- description = "foo"
- repository = "bar"
- "#))
- .file("src/main.rs", r#"
- fn main() {}
- "#);
- assert_that(p.cargo_process("package"),
- execs().with_status(0).with_stderr(&format!("\
-[PACKAGING] foo v0.0.1 ({dir})
-[VERIFYING] foo v0.0.1 ({dir})
-[COMPILING] foo v0.0.1 ({dir}[..])
-",
- dir = p.url())));
-}
-
-#[test]
-fn package_verbose() {
- let root = paths::root().join("all");
- let p = git::repo(&root)
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.0.1"
- authors = []
- "#)
- .file("a/src/lib.rs", "");
- p.build();
- let mut cargo = ::cargo_process();
- cargo.cwd(p.root());
- assert_that(cargo.clone().arg("build"), execs().with_status(0));
-
- println!("package main repo");
- assert_that(cargo.clone().arg("package").arg("-v").arg("--no-verify"),
- execs().with_status(0).with_stderr("\
-[WARNING] manifest has no description[..]
-[PACKAGING] foo v0.0.1 ([..])
-[ARCHIVING] [..]
-[ARCHIVING] [..]
-"));
-
- println!("package sub-repo");
- assert_that(cargo.arg("package").arg("-v").arg("--no-verify")
- .cwd(p.root().join("a")),
- execs().with_status(0).with_stderr("\
-[WARNING] manifest has no description[..]
-[PACKAGING] a v0.0.1 ([..])
-[ARCHIVING] [..]
-[ARCHIVING] [..]
-"));
-}
-
-#[test]
-fn package_verification() {
- let p = project("all")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#);
- assert_that(p.cargo_process("build"),
- execs().with_status(0));
- assert_that(p.cargo("package"),
- execs().with_status(0).with_stderr(&format!("\
-[WARNING] manifest has no description[..]
-[PACKAGING] foo v0.0.1 ({dir})
-[VERIFYING] foo v0.0.1 ({dir})
-[COMPILING] foo v0.0.1 ({dir}[..])
-",
- dir = p.url())));
-}
-
-#[test]
-fn exclude() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- exclude = ["*.txt"]
- "#)
- .file("src/main.rs", r#"
- fn main() { println!("hello"); }
- "#)
- .file("bar.txt", "")
- .file("src/bar.txt", "");
-
- assert_that(p.cargo_process("package").arg("--no-verify").arg("-v"),
- execs().with_status(0).with_stderr("\
-[WARNING] manifest has no description[..]
-[PACKAGING] foo v0.0.1 ([..])
-[ARCHIVING] [..]
-[ARCHIVING] [..]
-"));
-}
-
-#[test]
-fn include() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- exclude = ["*.txt"]
- include = ["foo.txt", "**/*.rs", "Cargo.toml"]
- "#)
- .file("foo.txt", "")
- .file("src/main.rs", r#"
- fn main() { println!("hello"); }
- "#)
- .file("src/bar.txt", ""); // should be ignored when packaging
-
- assert_that(p.cargo_process("package").arg("--no-verify").arg("-v"),
- execs().with_status(0).with_stderr("\
-[WARNING] manifest has no description[..]
-[PACKAGING] foo v0.0.1 ([..])
-[ARCHIVING] [..]
-[ARCHIVING] [..]
-[ARCHIVING] [..]
-"));
-}
-
-#[test]
-fn package_lib_with_bin() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- extern crate foo;
- fn main() {}
- "#)
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("package").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn package_new_git_repo() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
- git2::Repository::init(&p.root()).unwrap();
-
- assert_that(::cargo_process().arg("package").cwd(p.root())
- .arg("--no-verify").arg("-v"),
- execs().with_status(0).with_stderr("\
-[WARNING] manifest has no description[..]
-[PACKAGING] foo v0.0.1 ([..])
-[ARCHIVING] [..]
-[ARCHIVING] [..]
-"));
-}
-
-#[test]
-fn package_git_submodule() {
- let project = git::new("foo", |project| {
- project.file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = ["foo@example.com"]
- license = "MIT"
- description = "foo"
- repository = "foo"
- "#)
- .file("src/lib.rs", "pub fn foo() {}")
- }).unwrap();
- let library = git::new("bar", |library| {
- library.file("Makefile", "all:")
- }).unwrap();
-
- let repository = git2::Repository::open(&project.root()).unwrap();
- let url = path2url(library.root()).to_string();
- git::add_submodule(&repository, &url, Path::new("bar"));
- git::commit(&repository);
-
- let repository = git2::Repository::open(&project.root().join("bar")).unwrap();
- repository.reset(&repository.revparse_single("HEAD").unwrap(),
- git2::ResetType::Hard, None).unwrap();
-
- assert_that(::cargo_process().arg("package").cwd(project.root())
- .arg("--no-verify").arg("-v"),
- execs().with_status(0).with_stderr_contains("[ARCHIVING] bar/Makefile"));
-}
-
-#[test]
-fn no_duplicates_from_modified_tracked_files() {
- let root = paths::root().join("all");
- let p = git::repo(&root)
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#);
- p.build();
- File::create(p.root().join("src/main.rs")).unwrap().write_all(r#"
- fn main() { println!("A change!"); }
- "#.as_bytes()).unwrap();
- let mut cargo = ::cargo_process();
- cargo.cwd(p.root());
- assert_that(cargo.clone().arg("build"), execs().with_status(0));
- assert_that(cargo.arg("package").arg("--list"),
- execs().with_status(0).with_stdout("\
-Cargo.toml
-src/main.rs
-"));
-}
-
-#[test]
-fn ignore_nested() {
- let cargo_toml = r#"
- [project]
- name = "nested"
- version = "0.0.1"
- authors = []
- license = "MIT"
- description = "nested"
- "#;
- let main_rs = r#"
- fn main() { println!("hello"); }
- "#;
- let p = project("nested")
- .file("Cargo.toml", cargo_toml)
- .file("src/main.rs", main_rs)
- // If a project happens to contain a copy of itself, we should
- // ignore it.
- .file("a_dir/nested/Cargo.toml", cargo_toml)
- .file("a_dir/nested/src/main.rs", main_rs);
-
- assert_that(p.cargo_process("package"),
- execs().with_status(0).with_stderr(&format!("\
-[WARNING] manifest has no documentation[..]
-[PACKAGING] nested v0.0.1 ({dir})
-[VERIFYING] nested v0.0.1 ({dir})
-[COMPILING] nested v0.0.1 ({dir}[..])
-",
- dir = p.url())));
- assert_that(&p.root().join("target/package/nested-0.0.1.crate"), existing_file());
- assert_that(p.cargo("package").arg("-l"),
- execs().with_status(0).with_stdout("\
-Cargo.toml
-src[..]main.rs
-"));
- assert_that(p.cargo("package"),
- execs().with_status(0).with_stdout(""));
-
- let f = File::open(&p.root().join("target/package/nested-0.0.1.crate")).unwrap();
- let mut rdr = GzDecoder::new(f).unwrap();
- let mut contents = Vec::new();
- rdr.read_to_end(&mut contents).unwrap();
- let mut ar = Archive::new(&contents[..]);
- for f in ar.entries().unwrap() {
- let f = f.unwrap();
- let fname = f.header().path_bytes();
- let fname = &*fname;
- assert!(fname == b"nested-0.0.1/Cargo.toml" ||
- fname == b"nested-0.0.1/src/main.rs",
- "unexpected filename: {:?}", f.header().path())
- }
-}
-
-#[cfg(unix)] // windows doesn't allow these characters in filenames
-#[test]
-fn package_weird_characters() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() { println!("hello"); }
- "#)
- .file("src/:foo", "");
-
- assert_that(p.cargo_process("package"),
- execs().with_status(101).with_stderr("\
-warning: [..]
-[PACKAGING] foo [..]
-[ERROR] failed to prepare local package for uploading
-
-Caused by:
- cannot package a filename with a special character `:`: src/:foo
-"));
-}
+++ /dev/null
-use std::env;
-use std::path::MAIN_SEPARATOR as SEP;
-
-use support::{project, execs};
-use hamcrest::assert_that;
-
-#[test]
-fn profile_overrides() {
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [package]
-
- name = "test"
- version = "0.0.0"
- authors = []
-
- [profile.dev]
- opt-level = 1
- debug = false
- rpath = true
- "#)
- .file("src/lib.rs", "");
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0).with_stderr(&format!("\
-[COMPILING] test v0.0.0 ({url})
-[RUNNING] `rustc src{sep}lib.rs --crate-name test --crate-type lib \
- -C opt-level=1 \
- -C debug-assertions=on \
- -C rpath \
- --out-dir {dir}{sep}target{sep}debug \
- --emit=dep-info,link \
- -L dependency={dir}{sep}target{sep}debug \
- -L dependency={dir}{sep}target{sep}debug{sep}deps`
-", sep = SEP,
-dir = p.root().display(),
-url = p.url(),
-)));
-}
-
-#[test]
-fn top_level_overrides_deps() {
- let mut p = project("foo");
- p = p
- .file("Cargo.toml", r#"
- [package]
-
- name = "test"
- version = "0.0.0"
- authors = []
-
- [profile.release]
- opt-level = 1
- debug = true
-
- [dependencies.foo]
- path = "foo"
- "#)
- .file("src/lib.rs", "")
- .file("foo/Cargo.toml", r#"
- [package]
-
- name = "foo"
- version = "0.0.0"
- authors = []
-
- [profile.release]
- opt-level = 0
- debug = false
-
- [lib]
- name = "foo"
- crate_type = ["dylib", "rlib"]
- "#)
- .file("foo/src/lib.rs", "");
- assert_that(p.cargo_process("build").arg("-v").arg("--release"),
- execs().with_status(0).with_stderr(&format!("\
-[COMPILING] foo v0.0.0 ({url}/foo)
-[RUNNING] `rustc foo{sep}src{sep}lib.rs --crate-name foo \
- --crate-type dylib --crate-type rlib -C prefer-dynamic \
- -C opt-level=1 \
- -g \
- -C metadata=[..] \
- -C extra-filename=-[..] \
- --out-dir {dir}{sep}target{sep}release{sep}deps \
- --emit=dep-info,link \
- -L dependency={dir}{sep}target{sep}release{sep}deps \
- -L dependency={dir}{sep}target{sep}release{sep}deps`
-[COMPILING] test v0.0.0 ({url})
-[RUNNING] `rustc src{sep}lib.rs --crate-name test --crate-type lib \
- -C opt-level=1 \
- -g \
- --out-dir {dir}{sep}target{sep}release \
- --emit=dep-info,link \
- -L dependency={dir}{sep}target{sep}release \
- -L dependency={dir}{sep}target{sep}release{sep}deps \
- --extern foo={dir}{sep}target{sep}release{sep}deps{sep}\
- {prefix}foo-[..]{suffix} \
- --extern foo={dir}{sep}target{sep}release{sep}deps{sep}libfoo-[..].rlib`
-",
- dir = p.root().display(),
- url = p.url(),
- sep = SEP,
- prefix = env::consts::DLL_PREFIX,
- suffix = env::consts::DLL_SUFFIX)));
-}
+++ /dev/null
-use std::io::prelude::*;
-use std::fs::{self, File};
-use std::io::SeekFrom;
-use std::path::PathBuf;
-
-use flate2::read::GzDecoder;
-use tar::Archive;
-use url::Url;
-
-use support::{project, execs};
-use support::paths;
-use support::git::repo;
-
-use hamcrest::assert_that;
-
-fn registry_path() -> PathBuf { paths::root().join("registry") }
-fn registry() -> Url { Url::from_file_path(&*registry_path()).ok().unwrap() }
-fn upload_path() -> PathBuf { paths::root().join("upload") }
-fn upload() -> Url { Url::from_file_path(&*upload_path()).ok().unwrap() }
-
-fn setup() {
- let config = paths::root().join(".cargo/config");
- fs::create_dir_all(config.parent().unwrap()).unwrap();
- File::create(&config).unwrap().write_all(&format!(r#"
- [registry]
- index = "{reg}"
- token = "api-token"
- "#, reg = registry()).as_bytes()).unwrap();
- fs::create_dir_all(&upload_path().join("api/v1/crates")).unwrap();
-
- repo(®istry_path())
- .file("config.json", &format!(r#"{{
- "dl": "{0}",
- "api": "{0}"
- }}"#, upload()))
- .build();
-}
-
-#[test]
-fn simple() {
- setup();
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- license = "MIT"
- description = "foo"
- "#)
- .file("src/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("publish").arg("--no-verify"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] registry `{reg}`
-[WARNING] manifest has no documentation, [..]
-[PACKAGING] foo v0.0.1 ({dir})
-[UPLOADING] foo v0.0.1 ({dir})
-",
- dir = p.url(),
- reg = registry())));
-
- let mut f = File::open(&upload_path().join("api/v1/crates/new")).unwrap();
- // Skip the metadata payload and the size of the tarball
- let mut sz = [0; 4];
- assert_eq!(f.read(&mut sz).unwrap(), 4);
- let sz = ((sz[0] as u32) << 0) |
- ((sz[1] as u32) << 8) |
- ((sz[2] as u32) << 16) |
- ((sz[3] as u32) << 24);
- f.seek(SeekFrom::Current(sz as i64 + 4)).unwrap();
-
- // Verify the tarball
- let mut rdr = GzDecoder::new(f).unwrap();
- assert_eq!(rdr.header().filename().unwrap(), "foo-0.0.1.crate".as_bytes());
- let mut contents = Vec::new();
- rdr.read_to_end(&mut contents).unwrap();
- let mut ar = Archive::new(&contents[..]);
- for file in ar.entries().unwrap() {
- let file = file.unwrap();
- let fname = file.header().path_bytes();
- let fname = &*fname;
- assert!(fname == b"foo-0.0.1/Cargo.toml" ||
- fname == b"foo-0.0.1/src/main.rs",
- "unexpected filename: {:?}", file.header().path());
- }
-}
-
-#[test]
-fn git_deps() {
- setup();
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- license = "MIT"
- description = "foo"
-
- [dependencies.foo]
- git = "git://path/to/nowhere"
- "#)
- .file("src/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("publish").arg("-v").arg("--no-verify"),
- execs().with_status(101).with_stderr("\
-[UPDATING] registry [..]
-[ERROR] all dependencies must come from the same source.
-dependency `foo` comes from git://path/to/nowhere instead
-"));
-}
-
-#[test]
-fn path_dependency_no_version() {
- setup();
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- license = "MIT"
- description = "foo"
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", "");
-
- assert_that(p.cargo_process("publish"),
- execs().with_status(101).with_stderr("\
-[UPDATING] registry [..]
-[ERROR] all path dependencies must have a version specified when publishing.
-dependency `bar` does not specify a version
-"));
-}
-
-#[test]
-fn unpublishable_crate() {
- setup();
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- license = "MIT"
- description = "foo"
- publish = false
- "#)
- .file("src/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("publish"),
- execs().with_status(101).with_stderr("\
-[ERROR] some crates cannot be published.
-`foo` is marked as unpublishable
-"));
-}
+++ /dev/null
-use support::{project, execs, main_file, basic_bin_manifest};
-use hamcrest::{assert_that};
-
-fn remove_all_whitespace(s: &str) -> String {
- s.split_whitespace().collect()
-}
-
-fn read_manifest_output() -> String {
- remove_all_whitespace(r#"
-{
- "name":"foo",
- "version":"0.5.0",
- "id":"foo[..]0.5.0[..](path+file://[..]/foo)",
- "source":null,
- "dependencies":[],
- "targets":[{
- "kind":["bin"],
- "name":"foo",
- "src_path":"src[..]foo.rs"
- }],
- "features":{},
- "manifest_path":"[..]Cargo.toml"
-}"#)
-}
-
-#[test]
-fn cargo_read_manifest_path_to_cargo_toml_relative() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("read-manifest")
- .arg("--manifest-path").arg("foo/Cargo.toml")
- .cwd(p.root().parent().unwrap()),
- execs().with_status(0)
- .with_stdout(read_manifest_output()));
-}
-
-#[test]
-fn cargo_read_manifest_path_to_cargo_toml_absolute() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("read-manifest")
- .arg("--manifest-path").arg(p.root().join("Cargo.toml"))
- .cwd(p.root().parent().unwrap()),
- execs().with_status(0)
- .with_stdout(read_manifest_output()));
-}
-
-#[test]
-fn cargo_read_manifest_path_to_cargo_toml_parent_relative() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("read-manifest")
- .arg("--manifest-path").arg("foo")
- .cwd(p.root().parent().unwrap()),
- execs().with_status(101)
- .with_stderr("[ERROR] the manifest-path must be \
- a path to a Cargo.toml file"));
-}
-
-#[test]
-fn cargo_read_manifest_path_to_cargo_toml_parent_absolute() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("read-manifest")
- .arg("--manifest-path").arg(p.root())
- .cwd(p.root().parent().unwrap()),
- execs().with_status(101)
- .with_stderr("[ERROR] the manifest-path must be \
- a path to a Cargo.toml file"));
-}
-
-#[test]
-fn cargo_read_manifest_cwd() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("read-manifest")
- .cwd(p.root()),
- execs().with_status(0)
- .with_stdout(read_manifest_output()));
-}
+++ /dev/null
-use std::fs::{self, File};
-use std::io::prelude::*;
-
-use support::{project, execs};
-use support::paths::{self, CargoPathExt};
-use support::registry::{self, Package};
-use support::git;
-
-use hamcrest::assert_that;
-
-#[test]
-fn simple() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = ">= 0.0.0"
- "#)
- .file("src/main.rs", "fn main() {}");
-
- Package::new("bar", "0.0.1").publish();
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] registry `{reg}`
-[DOWNLOADING] bar v0.0.1 (registry file://[..])
-[COMPILING] bar v0.0.1 (registry file://[..])
-[COMPILING] foo v0.0.1 ({dir})
-",
- dir = p.url(),
- reg = registry::registry())));
-
- // Don't download a second time
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] registry `{reg}`
-[..] bar v0.0.1 (registry file://[..])
-[..] foo v0.0.1 ({dir})
-",
- dir = p.url(),
- reg = registry::registry())));
-}
-
-#[test]
-fn deps() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = ">= 0.0.0"
- "#)
- .file("src/main.rs", "fn main() {}");
-
- Package::new("baz", "0.0.1").publish();
- Package::new("bar", "0.0.1").dep("baz", "*").publish();
-
- assert_that(p.cargo_process("build"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] registry `{reg}`
-[DOWNLOADING] [..] v0.0.1 (registry file://[..])
-[DOWNLOADING] [..] v0.0.1 (registry file://[..])
-[COMPILING] baz v0.0.1 (registry file://[..])
-[COMPILING] bar v0.0.1 (registry file://[..])
-[COMPILING] foo v0.0.1 ({dir})
-",
- dir = p.url(),
- reg = registry::registry())));
-}
-
-#[test]
-fn nonexistent() {
- Package::new("init", "0.0.1").publish();
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- nonexistent = ">= 0.0.0"
- "#)
- .file("src/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr("\
-[UPDATING] registry [..]
-[ERROR] no matching package named `nonexistent` found (required by `foo`)
-location searched: registry file://[..]
-version required: >= 0.0.0
-"));
-}
-
-#[test]
-fn wrong_version() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- foo = ">= 1.0.0"
- "#)
- .file("src/main.rs", "fn main() {}");
-
- Package::new("foo", "0.0.1").publish();
- Package::new("foo", "0.0.2").publish();
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr_contains("\
-[ERROR] no matching package named `foo` found (required by `foo`)
-location searched: registry file://[..]
-version required: >= 1.0.0
-versions found: 0.0.2, 0.0.1
-"));
-
- Package::new("foo", "0.0.3").publish();
- Package::new("foo", "0.0.4").publish();
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr_contains("\
-[ERROR] no matching package named `foo` found (required by `foo`)
-location searched: registry file://[..]
-version required: >= 1.0.0
-versions found: 0.0.4, 0.0.3, 0.0.2, ...
-"));
-}
-
-#[test]
-fn bad_cksum() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bad-cksum = ">= 0.0.0"
- "#)
- .file("src/main.rs", "fn main() {}");
-
- let pkg = Package::new("bad-cksum", "0.0.1");
- pkg.publish();
- File::create(&pkg.archive_dst()).unwrap();
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(101).with_stderr("\
-[UPDATING] registry [..]
-[DOWNLOADING] bad-cksum [..]
-[ERROR] unable to get packages from source
-
-Caused by:
- failed to download package `bad-cksum v0.0.1 (registry file://[..])` from [..]
-
-Caused by:
- failed to verify the checksum of `bad-cksum v0.0.1 (registry file://[..])`
-"));
-}
-
-#[test]
-fn update_registry() {
- Package::new("init", "0.0.1").publish();
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- notyet = ">= 0.0.0"
- "#)
- .file("src/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("build"),
- execs().with_status(101).with_stderr_contains("\
-[ERROR] no matching package named `notyet` found (required by `foo`)
-location searched: registry file://[..]
-version required: >= 0.0.0
-"));
-
- Package::new("notyet", "0.0.1").publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] registry `{reg}`
-[DOWNLOADING] notyet v0.0.1 (registry file://[..])
-[COMPILING] notyet v0.0.1 (registry file://[..])
-[COMPILING] foo v0.0.1 ({dir})
-",
- dir = p.url(),
- reg = registry::registry())));
-}
-
-#[test]
-fn package_with_path_deps() {
- Package::new("init", "0.0.1").publish();
-
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- license = "MIT"
- description = "foo"
- repository = "bar"
-
- [dependencies.notyet]
- version = "0.0.1"
- path = "notyet"
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("notyet/Cargo.toml", r#"
- [package]
- name = "notyet"
- version = "0.0.1"
- authors = []
- "#)
- .file("notyet/src/lib.rs", "");
- p.build();
-
- assert_that(p.cargo("package").arg("-v"),
- execs().with_status(101).with_stderr_contains("\
-[ERROR] failed to verify package tarball
-
-Caused by:
- no matching package named `notyet` found (required by `foo`)
-location searched: registry file://[..]
-version required: ^0.0.1
-"));
-
- Package::new("notyet", "0.0.1").publish();
-
- assert_that(p.cargo("package"),
- execs().with_status(0).with_stderr(format!("\
-[PACKAGING] foo v0.0.1 ({dir})
-[VERIFYING] foo v0.0.1 ({dir})
-[UPDATING] registry `[..]`
-[DOWNLOADING] notyet v0.0.1 (registry file://[..])
-[COMPILING] notyet v0.0.1 (registry file://[..])
-[COMPILING] foo v0.0.1 ({dir}[..])
-", dir = p.url())));
-}
-
-#[test]
-fn lockfile_locks() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "*"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("bar", "0.0.1").publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] registry `[..]`
-[DOWNLOADING] bar v0.0.1 (registry file://[..])
-[COMPILING] bar v0.0.1 (registry file://[..])
-[COMPILING] foo v0.0.1 ({dir})
-",
- dir = p.url())));
-
- p.root().move_into_the_past().unwrap();
- Package::new("bar", "0.0.2").publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stdout(""));
-}
-
-#[test]
-fn lockfile_locks_transitively() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "*"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("baz", "0.0.1").publish();
- Package::new("bar", "0.0.1").dep("baz", "*").publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] registry `[..]`
-[DOWNLOADING] [..] v0.0.1 (registry file://[..])
-[DOWNLOADING] [..] v0.0.1 (registry file://[..])
-[COMPILING] baz v0.0.1 (registry file://[..])
-[COMPILING] bar v0.0.1 (registry file://[..])
-[COMPILING] foo v0.0.1 ({dir})
-",
- dir = p.url())));
-
- p.root().move_into_the_past().unwrap();
- Package::new("baz", "0.0.2").publish();
- Package::new("bar", "0.0.2").dep("baz", "*").publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stdout(""));
-}
-
-#[test]
-fn yanks_are_not_used() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "*"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("baz", "0.0.1").publish();
- Package::new("baz", "0.0.2").yanked(true).publish();
- Package::new("bar", "0.0.1").dep("baz", "*").publish();
- Package::new("bar", "0.0.2").dep("baz", "*").yanked(true).publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] registry `[..]`
-[DOWNLOADING] [..] v0.0.1 (registry file://[..])
-[DOWNLOADING] [..] v0.0.1 (registry file://[..])
-[COMPILING] baz v0.0.1 (registry file://[..])
-[COMPILING] bar v0.0.1 (registry file://[..])
-[COMPILING] foo v0.0.1 ({dir})
-",
- dir = p.url())));
-}
-
-#[test]
-fn relying_on_a_yank_is_bad() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "*"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("baz", "0.0.1").publish();
- Package::new("baz", "0.0.2").yanked(true).publish();
- Package::new("bar", "0.0.1").dep("baz", "=0.0.2").publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(101).with_stderr_contains("\
-[ERROR] no matching package named `baz` found (required by `bar`)
-location searched: registry file://[..]
-version required: = 0.0.2
-versions found: 0.0.1
-"));
-}
-
-#[test]
-fn yanks_in_lockfiles_are_ok() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "*"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("bar", "0.0.1").publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
-
- fs::remove_dir_all(®istry::registry_path().join("3")).unwrap();
-
- Package::new("bar", "0.0.1").yanked(true).publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stdout(""));
-
- assert_that(p.cargo("update"),
- execs().with_status(101).with_stderr_contains("\
-[ERROR] no matching package named `bar` found (required by `foo`)
-location searched: registry file://[..]
-version required: *
-"));
-}
-
-#[test]
-fn update_with_lockfile_if_packages_missing() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "*"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("bar", "0.0.1").publish();
- assert_that(p.cargo("build"),
- execs().with_status(0));
- p.root().move_into_the_past().unwrap();
-
- paths::home().join(".cargo/registry").rm_rf().unwrap();
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry `[..]`
-[DOWNLOADING] bar v0.0.1 (registry file://[..])
-"));
-}
-
-#[test]
-fn update_lockfile() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "*"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- println!("0.0.1");
- Package::new("bar", "0.0.1").publish();
- assert_that(p.cargo("build"),
- execs().with_status(0));
-
- Package::new("bar", "0.0.2").publish();
- Package::new("bar", "0.0.3").publish();
- paths::home().join(".cargo/registry").rm_rf().unwrap();
- println!("0.0.2 update");
- assert_that(p.cargo("update")
- .arg("-p").arg("bar").arg("--precise").arg("0.0.2"),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry `[..]`
-[UPDATING] bar v0.0.1 (registry file://[..]) -> v0.0.2
-"));
-
- println!("0.0.2 build");
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr(&format!("\
-[DOWNLOADING] [..] v0.0.2 (registry file://[..])
-[COMPILING] bar v0.0.2 (registry file://[..])
-[COMPILING] foo v0.0.1 ({dir})
-",
- dir = p.url())));
-
- println!("0.0.3 update");
- assert_that(p.cargo("update")
- .arg("-p").arg("bar"),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry `[..]`
-[UPDATING] bar v0.0.2 (registry file://[..]) -> v0.0.3
-"));
-
- println!("0.0.3 build");
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr(&format!("\
-[DOWNLOADING] [..] v0.0.3 (registry file://[..])
-[COMPILING] bar v0.0.3 (registry file://[..])
-[COMPILING] foo v0.0.1 ({dir})
-",
- dir = p.url())));
-
- println!("new dependencies update");
- Package::new("bar", "0.0.4").dep("spam", "0.2.5").publish();
- Package::new("spam", "0.2.5").publish();
- assert_that(p.cargo("update")
- .arg("-p").arg("bar"),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry `[..]`
-[UPDATING] bar v0.0.3 (registry file://[..]) -> v0.0.4
-[ADDING] spam v0.2.5 (registry file://[..])
-"));
-
- println!("new dependencies update");
- Package::new("bar", "0.0.5").publish();
- assert_that(p.cargo("update")
- .arg("-p").arg("bar"),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry `[..]`
-[UPDATING] bar v0.0.4 (registry file://[..]) -> v0.0.5
-[REMOVING] spam v0.2.5 (registry file://[..])
-"));
-}
-
-#[test]
-fn dev_dependency_not_used() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "*"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("baz", "0.0.1").publish();
- Package::new("bar", "0.0.1").dev_dep("baz", "*").publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] registry `[..]`
-[DOWNLOADING] [..] v0.0.1 (registry file://[..])
-[COMPILING] bar v0.0.1 (registry file://[..])
-[COMPILING] foo v0.0.1 ({dir})
-",
- dir = p.url())));
-}
-
-#[test]
-fn login_with_no_cargo_dir() {
- let home = paths::home().join("new-home");
- fs::create_dir(&home).unwrap();
- assert_that(::cargo_process().arg("login").arg("foo").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn bad_license_file() {
- Package::new("foo", "1.0.0").publish();
- let p = project("all")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- license-file = "foo"
- description = "bar"
- repository = "baz"
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#);
- assert_that(p.cargo_process("publish").arg("-v"),
- execs().with_status(101)
- .with_stderr_contains("\
-[ERROR] the license file `foo` does not exist"));
-}
-
-#[test]
-fn updating_a_dep() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.a]
- path = "a"
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("a/Cargo.toml", r#"
- [project]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "*"
- "#)
- .file("a/src/lib.rs", "");
- p.build();
-
- Package::new("bar", "0.0.1").publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] registry `[..]`
-[DOWNLOADING] bar v0.0.1 (registry file://[..])
-[COMPILING] bar v0.0.1 (registry file://[..])
-[COMPILING] a v0.0.1 ({dir}/a)
-[COMPILING] foo v0.0.1 ({dir})
-",
- dir = p.url())));
-
- File::create(&p.root().join("a/Cargo.toml")).unwrap().write_all(br#"
- [project]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = "0.1.0"
- "#).unwrap();
- Package::new("bar", "0.1.0").publish();
-
- println!("second");
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] registry `[..]`
-[DOWNLOADING] bar v0.1.0 (registry file://[..])
-[COMPILING] bar v0.1.0 (registry file://[..])
-[COMPILING] a v0.0.1 ({dir}/a)
-[COMPILING] foo v0.0.1 ({dir})
-",
- dir = p.url())));
-}
-
-#[test]
-fn git_and_registry_dep() {
- let b = git::repo(&paths::root().join("b"))
- .file("Cargo.toml", r#"
- [project]
- name = "b"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- a = "0.0.1"
- "#)
- .file("src/lib.rs", "");
- b.build();
- let p = project("foo")
- .file("Cargo.toml", &format!(r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- a = "0.0.1"
-
- [dependencies.b]
- git = '{}'
- "#, b.url()))
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("a", "0.0.1").publish();
-
- p.root().move_into_the_past().unwrap();
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] [..]
-[UPDATING] [..]
-[DOWNLOADING] a v0.0.1 (registry file://[..])
-[COMPILING] a v0.0.1 (registry [..])
-[COMPILING] b v0.0.1 ([..])
-[COMPILING] foo v0.0.1 ({dir})
-",
- dir = p.url())));
- p.root().move_into_the_past().unwrap();
-
- println!("second");
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stdout(""));
-}
-
-#[test]
-fn update_publish_then_update() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
-
- [dependencies]
- a = "0.1.0"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("a", "0.1.0").publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
-
- Package::new("a", "0.1.1").publish();
-
- let lock = p.root().join("Cargo.lock");
- let mut s = String::new();
- File::open(&lock).unwrap().read_to_string(&mut s).unwrap();
- File::create(&lock).unwrap()
- .write_all(s.replace("0.1.0", "0.1.1").as_bytes()).unwrap();
- println!("second");
-
- fs::remove_dir_all(&p.root().join("target")).unwrap();
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr(&format!("\
-[UPDATING] [..]
-[DOWNLOADING] a v0.1.1 (registry file://[..])
-[COMPILING] a v0.1.1 (registry [..])
-[COMPILING] foo v0.5.0 ({dir})
-",
- dir = p.url())));
-
-}
-
-#[test]
-fn fetch_downloads() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
-
- [dependencies]
- a = "0.1.0"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("a", "0.1.0").publish();
-
- assert_that(p.cargo("fetch"),
- execs().with_status(0)
- .with_stderr("\
-[UPDATING] registry `[..]`
-[DOWNLOADING] a v0.1.0 (registry [..])
-"));
-}
-
-#[test]
-fn update_transitive_dependency() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
-
- [dependencies]
- a = "0.1.0"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("a", "0.1.0").dep("b", "*").publish();
- Package::new("b", "0.1.0").publish();
-
- assert_that(p.cargo("fetch"),
- execs().with_status(0));
-
- Package::new("b", "0.1.1").publish();
-
- assert_that(p.cargo("update").arg("-pb"),
- execs().with_status(0)
- .with_stderr("\
-[UPDATING] registry `[..]`
-[UPDATING] b v0.1.0 (registry [..]) -> v0.1.1
-"));
-
- assert_that(p.cargo("build"),
- execs().with_status(0)
- .with_stderr("\
-[DOWNLOADING] b v0.1.1 (registry file://[..])
-[COMPILING] b v0.1.1 (registry [..])
-[COMPILING] a v0.1.0 (registry [..])
-[COMPILING] foo v0.5.0 ([..])
-"));
-}
-
-#[test]
-fn update_backtracking_ok() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
-
- [dependencies]
- webdriver = "0.1"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("webdriver", "0.1.0").dep("hyper", "0.6").publish();
- Package::new("hyper", "0.6.5").dep("openssl", "0.1")
- .dep("cookie", "0.1")
- .publish();
- Package::new("cookie", "0.1.0").dep("openssl", "0.1").publish();
- Package::new("openssl", "0.1.0").publish();
-
- assert_that(p.cargo("generate-lockfile"),
- execs().with_status(0));
-
- Package::new("openssl", "0.1.1").publish();
- Package::new("hyper", "0.6.6").dep("openssl", "0.1.1")
- .dep("cookie", "0.1.0")
- .publish();
-
- assert_that(p.cargo("update").arg("-p").arg("hyper"),
- execs().with_status(0)
- .with_stderr("\
-[UPDATING] registry `[..]`
-"));
-}
-
-#[test]
-fn update_multiple_packages() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
-
- [dependencies]
- a = "*"
- b = "*"
- c = "*"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("a", "0.1.0").publish();
- Package::new("b", "0.1.0").publish();
- Package::new("c", "0.1.0").publish();
-
- assert_that(p.cargo("fetch"),
- execs().with_status(0));
-
- Package::new("a", "0.1.1").publish();
- Package::new("b", "0.1.1").publish();
- Package::new("c", "0.1.1").publish();
-
- assert_that(p.cargo("update").arg("-pa").arg("-pb"),
- execs().with_status(0)
- .with_stderr("\
-[UPDATING] registry `[..]`
-[UPDATING] a v0.1.0 (registry [..]) -> v0.1.1
-[UPDATING] b v0.1.0 (registry [..]) -> v0.1.1
-"));
-
- assert_that(p.cargo("update").arg("-pb").arg("-pc"),
- execs().with_status(0)
- .with_stderr("\
-[UPDATING] registry `[..]`
-[UPDATING] c v0.1.0 (registry [..]) -> v0.1.1
-"));
-
- assert_that(p.cargo("build"),
- execs().with_status(0)
- .with_stderr_contains("\
-[DOWNLOADING] a v0.1.1 (registry file://[..])")
- .with_stderr_contains("\
-[DOWNLOADING] b v0.1.1 (registry file://[..])")
- .with_stderr_contains("\
-[DOWNLOADING] c v0.1.1 (registry file://[..])")
- .with_stderr_contains("\
-[COMPILING] a v0.1.1 (registry [..])")
- .with_stderr_contains("\
-[COMPILING] b v0.1.1 (registry [..])")
- .with_stderr_contains("\
-[COMPILING] c v0.1.1 (registry [..])")
- .with_stderr_contains("\
-[COMPILING] foo v0.5.0 ([..])"));
-}
-
-#[test]
-fn bundled_crate_in_registry() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
-
- [dependencies]
- bar = "0.1"
- baz = "0.1"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("bar", "0.1.0").publish();
- Package::new("baz", "0.1.0")
- .dep("bar", "0.1.0")
- .file("Cargo.toml", r#"
- [package]
- name = "baz"
- version = "0.1.0"
- authors = []
-
- [dependencies]
- bar = { path = "bar", version = "0.1.0" }
- "#)
- .file("src/lib.rs", "")
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.1.0"
- authors = []
- "#)
- .file("bar/src/lib.rs", "")
- .publish();
-
- assert_that(p.cargo("run"), execs().with_status(0));
-}
-
-#[test]
-fn update_same_prefix_oh_my_how_was_this_a_bug() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "ugh"
- version = "0.5.0"
- authors = []
-
- [dependencies]
- foo = "0.1"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("foobar", "0.2.0").publish();
- Package::new("foo", "0.1.0")
- .dep("foobar", "0.2.0")
- .publish();
-
- assert_that(p.cargo("generate-lockfile"), execs().with_status(0));
- assert_that(p.cargo("update").arg("-pfoobar").arg("--precise=0.2.0"),
- execs().with_status(0));
-}
-
-#[test]
-fn use_semver() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "bar"
- version = "0.5.0"
- authors = []
-
- [dependencies]
- foo = "1.2.3-alpha.0"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("foo", "1.2.3-alpha.0").publish();
-
- assert_that(p.cargo("build"), execs().with_status(0));
-}
-
-#[test]
-fn only_download_relevant() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "bar"
- version = "0.5.0"
- authors = []
-
- [target.foo.dependencies]
- foo = "*"
- [dev-dependencies]
- bar = "*"
- [dependencies]
- baz = "*"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("foo", "0.1.0").publish();
- Package::new("bar", "0.1.0").publish();
- Package::new("baz", "0.1.0").publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(0).with_stderr("\
-[UPDATING] registry `[..]`
-[DOWNLOADING] baz v0.1.0 ([..])
-[COMPILING] baz v0.1.0 ([..])
-[COMPILING] bar v0.5.0 ([..])
-"));
-}
-
-#[test]
-fn resolve_and_backtracking() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "bar"
- version = "0.5.0"
- authors = []
-
- [dependencies]
- foo = "*"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
-
- Package::new("foo", "0.1.1")
- .feature_dep("bar", "0.1", &["a", "b"])
- .publish();
- Package::new("foo", "0.1.0").publish();
-
- assert_that(p.cargo("build"),
- execs().with_status(0));
-}
+++ /dev/null
-use std::path::MAIN_SEPARATOR as SEP;
-
-use support::{project, execs, path2url};
-use hamcrest::{assert_that, existing_file};
-
-#[test]
-fn simple() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() { println!("hello"); }
- "#);
-
- assert_that(p.cargo_process("run"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] `target{sep}debug{sep}foo[..]`", dir = path2url(p.root()), sep = SEP))
- .with_stdout("\
-hello
-"));
- assert_that(&p.bin("foo"), existing_file());
-}
-
-#[test]
-fn simple_quiet() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() { println!("hello"); }
- "#);
-
- assert_that(p.cargo_process("run").arg("-q"),
- execs().with_status(0).with_stdout("\
-hello
-")
- );
-}
-
-#[test]
-fn simple_quiet_and_verbose() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() { println!("hello"); }
- "#);
-
- assert_that(p.cargo_process("run").arg("-q").arg("-v"),
- execs().with_status(101).with_stderr("\
-[ERROR] cannot set both --verbose and --quiet
-"));
-}
-
-#[test]
-fn quiet_and_verbose_config() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file(".cargo/config", r#"
- [term]
- verbose = true
- "#)
- .file("src/main.rs", r#"
- fn main() { println!("hello"); }
- "#);
-
- assert_that(p.cargo_process("run").arg("-q"),
- execs().with_status(0));
-}
-
-#[test]
-fn simple_with_args() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {
- assert_eq!(std::env::args().nth(1).unwrap(), "hello");
- assert_eq!(std::env::args().nth(2).unwrap(), "world");
- }
- "#);
-
- assert_that(p.cargo_process("run").arg("hello").arg("world"),
- execs().with_status(0));
-}
-
-#[test]
-fn exit_code() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() { std::process::exit(2); }
- "#);
-
- assert_that(p.cargo_process("run"),
- execs().with_status(2)
- .with_stderr("\
-[COMPILING] foo v0.0.1 (file[..])
-[RUNNING] `target[..]`
-[ERROR] Process didn't exit successfully: `target[..]foo[..]` (exit code: 2)
-"));
-}
-
-#[test]
-fn exit_code_verbose() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() { std::process::exit(2); }
- "#);
-
- assert_that(p.cargo_process("run").arg("-v"),
- execs().with_status(2)
- .with_stderr("\
-[COMPILING] foo v0.0.1 (file[..])
-[RUNNING] `rustc [..]`
-[RUNNING] `target[..]`
-[ERROR] Process didn't exit successfully: `target[..]foo[..]` (exit code: 2)
-"));
-}
-
-#[test]
-fn no_main_file() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("run"),
- execs().with_status(101)
- .with_stderr("[ERROR] a bin target must be available \
- for `cargo run`\n"));
-}
-
-#[test]
-fn too_many_bins() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file("src/bin/a.rs", "")
- .file("src/bin/b.rs", "");
-
- assert_that(p.cargo_process("run"),
- execs().with_status(101)
- .with_stderr("[ERROR] `cargo run` requires that a project only \
- have one executable; use the `--bin` option \
- to specify which one to run\n"));
-}
-
-#[test]
-fn specify_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file("src/bin/a.rs", r#"
- extern crate foo;
- fn main() { println!("hello a.rs"); }
- "#)
- .file("src/bin/b.rs", r#"
- extern crate foo;
- fn main() { println!("hello b.rs"); }
- "#);
-
- assert_that(p.cargo_process("run").arg("--bin").arg("a").arg("-v"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] `rustc src[..]lib.rs [..]`
-[RUNNING] `rustc src[..]a.rs [..]`
-[RUNNING] `target{sep}debug{sep}a[..]`", dir = path2url(p.root()), sep = SEP))
- .with_stdout("\
-hello a.rs
-"));
-
- assert_that(p.cargo("run").arg("--bin").arg("b").arg("-v"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ([..])
-[RUNNING] `rustc src[..]b.rs [..]`
-[RUNNING] `target{sep}debug{sep}b[..]`", sep = SEP))
- .with_stdout("\
-hello b.rs
-"));
-}
-
-#[test]
-fn run_example() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file("examples/a.rs", r#"
- fn main() { println!("example"); }
- "#)
- .file("src/bin/a.rs", r#"
- fn main() { println!("bin"); }
- "#);
-
- assert_that(p.cargo_process("run").arg("--example").arg("a"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] `target{sep}debug{sep}examples{sep}a[..]`", dir = path2url(p.root()), sep = SEP))
- .with_stdout("\
-example
-"));
-}
-
-#[test]
-fn run_with_filename() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file("src/bin/a.rs", r#"
- extern crate foo;
- fn main() { println!("hello a.rs"); }
- "#)
- .file("examples/a.rs", r#"
- fn main() { println!("example"); }
- "#);
-
- assert_that(p.cargo_process("run").arg("--bin").arg("bin.rs"),
- execs().with_status(101).with_stderr("\
-[ERROR] no bin target named `bin.rs`"));
-
- assert_that(p.cargo_process("run").arg("--bin").arg("a.rs"),
- execs().with_status(101).with_stderr("\
-[ERROR] no bin target named `a.rs`
-
-Did you mean `a`?"));
-
- assert_that(p.cargo_process("run").arg("--example").arg("example.rs"),
- execs().with_status(101).with_stderr("\
-[ERROR] no example target named `example.rs`"));
-
- assert_that(p.cargo_process("run").arg("--example").arg("a.rs"),
- execs().with_status(101).with_stderr("\
-[ERROR] no example target named `a.rs`
-
-Did you mean `a`?"));
-}
-
-#[test]
-fn either_name_or_example() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/bin/a.rs", r#"
- fn main() { println!("hello a.rs"); }
- "#)
- .file("examples/b.rs", r#"
- fn main() { println!("hello b.rs"); }
- "#);
-
- assert_that(p.cargo_process("run").arg("--bin").arg("a").arg("--example").arg("b"),
- execs().with_status(101)
- .with_stderr("[ERROR] `cargo run` can run at most one \
- executable, but multiple were \
- specified"));
-}
-
-#[test]
-fn one_bin_multiple_examples() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file("src/bin/main.rs", r#"
- fn main() { println!("hello main.rs"); }
- "#)
- .file("examples/a.rs", r#"
- fn main() { println!("hello a.rs"); }
- "#)
- .file("examples/b.rs", r#"
- fn main() { println!("hello b.rs"); }
- "#);
-
- assert_that(p.cargo_process("run"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] `target{sep}debug{sep}main[..]`", dir = path2url(p.root()), sep = SEP))
- .with_stdout("\
-hello main.rs
-"));
-}
-
-#[test]
-fn example_with_release_flag() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- version = "*"
- path = "bar"
- "#)
- .file("examples/a.rs", r#"
- extern crate bar;
-
- fn main() {
- if cfg!(debug_assertions) {
- println!("slow1")
- } else {
- println!("fast1")
- }
- bar::baz();
- }
- "#)
- .file("bar/Cargo.toml", r#"
- [project]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "bar"
- "#)
- .file("bar/src/bar.rs", r#"
- pub fn baz() {
- if cfg!(debug_assertions) {
- println!("slow2")
- } else {
- println!("fast2")
- }
- }
- "#);
-
- assert_that(p.cargo_process("run").arg("-v").arg("--release").arg("--example").arg("a"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] bar v0.0.1 ({url}/bar)
-[RUNNING] `rustc bar{sep}src{sep}bar.rs --crate-name bar --crate-type lib \
- -C opt-level=3 \
- -C metadata=[..] \
- -C extra-filename=[..] \
- --out-dir {dir}{sep}target{sep}release{sep}deps \
- --emit=dep-info,link \
- -L dependency={dir}{sep}target{sep}release{sep}deps \
- -L dependency={dir}{sep}target{sep}release{sep}deps`
-[COMPILING] foo v0.0.1 ({url})
-[RUNNING] `rustc examples{sep}a.rs --crate-name a --crate-type bin \
- -C opt-level=3 \
- --out-dir {dir}{sep}target{sep}release{sep}examples \
- --emit=dep-info,link \
- -L dependency={dir}{sep}target{sep}release \
- -L dependency={dir}{sep}target{sep}release{sep}deps \
- --extern bar={dir}{sep}target{sep}release{sep}deps{sep}libbar-[..].rlib`
-[RUNNING] `target{sep}release{sep}examples{sep}a[..]`
-",
- dir = p.root().display(),
- url = path2url(p.root()),
- sep = SEP))
- .with_stdout("\
-fast1
-fast2"));
-
- assert_that(p.cargo("run").arg("-v").arg("--example").arg("a"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] bar v0.0.1 ({url}/bar)
-[RUNNING] `rustc bar{sep}src{sep}bar.rs --crate-name bar --crate-type lib \
- -g \
- -C metadata=[..] \
- -C extra-filename=[..] \
- --out-dir {dir}{sep}target{sep}debug{sep}deps \
- --emit=dep-info,link \
- -L dependency={dir}{sep}target{sep}debug{sep}deps \
- -L dependency={dir}{sep}target{sep}debug{sep}deps`
-[COMPILING] foo v0.0.1 ({url})
-[RUNNING] `rustc examples{sep}a.rs --crate-name a --crate-type bin \
- -g \
- --out-dir {dir}{sep}target{sep}debug{sep}examples \
- --emit=dep-info,link \
- -L dependency={dir}{sep}target{sep}debug \
- -L dependency={dir}{sep}target{sep}debug{sep}deps \
- --extern bar={dir}{sep}target{sep}debug{sep}deps{sep}libbar-[..].rlib`
-[RUNNING] `target{sep}debug{sep}examples{sep}a[..]`
-",
- dir = p.root().display(),
- url = path2url(p.root()),
- sep = SEP))
- .with_stdout("\
-slow1
-slow2"));
-}
-
-#[test]
-fn run_dylib_dep() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/main.rs", r#"
- extern crate bar;
- fn main() { bar::bar(); }
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "bar"
- crate-type = ["dylib"]
- "#)
- .file("bar/src/lib.rs", "pub fn bar() {}");
-
- assert_that(p.cargo_process("run").arg("hello").arg("world"),
- execs().with_status(0));
-}
-
-#[test]
-fn release_works() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() { if cfg!(debug_assertions) { panic!() } }
- "#);
-
- assert_that(p.cargo_process("run").arg("--release"),
- execs().with_status(0).with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] `target{sep}release{sep}foo[..]`
-",
- dir = path2url(p.root()),
- sep = SEP)));
- assert_that(&p.release_bin("foo"), existing_file());
-}
-
-#[test]
-fn run_bin_different_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [[bin]]
- name = "bar"
- "#)
- .file("src/bar.rs", r#"
- fn main() { }
- "#);
-
- assert_that(p.cargo_process("run"), execs().with_status(0));
-}
-
-#[test]
-fn dashes_are_forwarded() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [[bin]]
- name = "bar"
- "#)
- .file("src/main.rs", r#"
- fn main() {
- let s: Vec<String> = std::env::args().collect();
- assert_eq!(s[1], "a");
- assert_eq!(s[2], "--");
- assert_eq!(s[3], "b");
- }
- "#);
-
- assert_that(p.cargo_process("run").arg("--").arg("a").arg("--").arg("b"),
- execs().with_status(0));
-}
-
-#[test]
-fn run_from_executable_folder() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() { println!("hello"); }
- "#);
-
- let cwd = p.root().join("target").join("debug");
- p.cargo_process("build").exec_with_output().unwrap();
-
- assert_that(p.cargo("run").cwd(cwd),
- execs().with_status(0)
- .with_stderr(&format!("\
-[RUNNING] `.{sep}foo[..]`", sep = SEP))
- .with_stdout("\
-hello
-"));
-}
+++ /dev/null
-use std::path::MAIN_SEPARATOR as SEP;
-
-use support::{execs, project};
-
-use hamcrest::assert_that;
-
-const CARGO_RUSTC_ERROR: &'static str =
-"[ERROR] extra arguments to `rustc` can only be passed to one target, consider filtering
-the package by passing e.g. `--lib` or `--bin NAME` to specify a single target";
-
-#[test]
-fn build_lib_for_foo() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("src/lib.rs", r#" "#);
-
- assert_that(p.cargo_process("rustc").arg("--lib").arg("-v"),
- execs()
- .with_status(0)
- .with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({url})
-[RUNNING] `rustc src{sep}lib.rs --crate-name foo --crate-type lib -g \
- --out-dir {dir}{sep}target{sep}debug \
- --emit=dep-info,link \
- -L dependency={dir}{sep}target{sep}debug \
- -L dependency={dir}{sep}target{sep}debug{sep}deps`
-", sep = SEP,
- dir = p.root().display(), url = p.url())));
-}
-
-#[test]
-fn lib() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("src/lib.rs", r#" "#);
-
- assert_that(p.cargo_process("rustc").arg("--lib").arg("-v")
- .arg("--").arg("-C").arg("debug-assertions=off"),
- execs()
- .with_status(0)
- .with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({url})
-[RUNNING] `rustc src{sep}lib.rs --crate-name foo --crate-type lib -g \
- -C debug-assertions=off \
- --out-dir {dir}{sep}target{sep}debug \
- --emit=dep-info,link \
- -L dependency={dir}{sep}target{sep}debug \
- -L dependency={dir}{sep}target{sep}debug{sep}deps`
-", sep = SEP,
- dir = p.root().display(), url = p.url())))
-}
-
-#[test]
-fn build_main_and_allow_unstable_options() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("src/lib.rs", r#" "#);
-
- assert_that(p.cargo_process("rustc").arg("-v").arg("--bin").arg("foo")
- .arg("--").arg("-C").arg("debug-assertions"),
- execs()
- .with_status(0)
- .with_stderr(&format!("\
-[COMPILING] {name} v{version} ({url})
-[RUNNING] `rustc src{sep}lib.rs --crate-name {name} --crate-type lib -g \
- --out-dir {dir}{sep}target{sep}debug \
- --emit=dep-info,link \
- -L dependency={dir}{sep}target{sep}debug \
- -L dependency={dir}{sep}target{sep}debug{sep}deps`
-[RUNNING] `rustc src{sep}main.rs --crate-name {name} --crate-type bin -g \
- -C debug-assertions \
- --out-dir {dir}{sep}target{sep}debug \
- --emit=dep-info,link \
- -L dependency={dir}{sep}target{sep}debug \
- -L dependency={dir}{sep}target{sep}debug{sep}deps \
- --extern {name}={dir}{sep}target{sep}debug{sep}lib{name}.rlib`
-", sep = SEP,
- dir = p.root().display(), url = p.url(),
- name = "foo", version = "0.0.1")));
-}
-
-#[test]
-fn fails_when_trying_to_build_main_and_lib_with_args() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("src/lib.rs", r#" "#);
-
- assert_that(p.cargo_process("rustc").arg("-v")
- .arg("--").arg("-C").arg("debug-assertions"),
- execs()
- .with_status(101)
- .with_stderr(CARGO_RUSTC_ERROR));
-}
-
-#[test]
-fn build_with_args_to_one_of_multiple_binaries() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/bin/foo.rs", r#"
- fn main() {}
- "#)
- .file("src/bin/bar.rs", r#"
- fn main() {}
- "#)
- .file("src/bin/baz.rs", r#"
- fn main() {}
- "#)
- .file("src/lib.rs", r#" "#);
-
- assert_that(p.cargo_process("rustc").arg("-v").arg("--bin").arg("bar")
- .arg("--").arg("-C").arg("debug-assertions"),
- execs()
- .with_status(0)
- .with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({url})
-[RUNNING] `rustc src{sep}lib.rs --crate-name foo --crate-type lib -g \
- --out-dir {dir}{sep}target{sep}debug [..]`
-[RUNNING] `rustc src{sep}bin{sep}bar.rs --crate-name bar --crate-type bin -g \
- -C debug-assertions [..]`
-", sep = SEP,
- dir = p.root().display(), url = p.url())));
-}
-
-#[test]
-fn fails_with_args_to_all_binaries() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/bin/foo.rs", r#"
- fn main() {}
- "#)
- .file("src/bin/bar.rs", r#"
- fn main() {}
- "#)
- .file("src/bin/baz.rs", r#"
- fn main() {}
- "#)
- .file("src/lib.rs", r#" "#);
-
- assert_that(p.cargo_process("rustc").arg("-v")
- .arg("--").arg("-C").arg("debug-assertions"),
- execs()
- .with_status(101)
- .with_stderr(CARGO_RUSTC_ERROR));
-}
-
-#[test]
-fn build_with_args_to_one_of_multiple_tests() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("tests/foo.rs", r#" "#)
- .file("tests/bar.rs", r#" "#)
- .file("tests/baz.rs", r#" "#)
- .file("src/lib.rs", r#" "#);
-
- assert_that(p.cargo_process("rustc").arg("-v").arg("--test").arg("bar")
- .arg("--").arg("-C").arg("debug-assertions"),
- execs()
- .with_status(0)
- .with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({url})
-[RUNNING] `rustc src{sep}lib.rs --crate-name foo --crate-type lib -g \
- --out-dir {dir}{sep}target{sep}debug [..]`
-[RUNNING] `rustc tests{sep}bar.rs --crate-name bar --crate-type bin -g \
- -C debug-assertions [..]--test[..]`
-", sep = SEP,
- dir = p.root().display(), url = p.url())));
-}
-
-#[test]
-fn build_foo_with_bar_dependency() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "../bar"
- "#)
- .file("src/main.rs", r#"
- extern crate bar;
- fn main() {
- bar::baz()
- }
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- pub fn baz() {}
- "#);
- bar.build();
-
- assert_that(foo.cargo_process("rustc").arg("-v").arg("--").arg("-C").arg("debug-assertions"),
- execs()
- .with_status(0)
- .with_stderr(format!("\
-[COMPILING] bar v0.1.0 ([..])
-[RUNNING] `[..] -g -C [..]`
-[COMPILING] foo v0.0.1 ({url})
-[RUNNING] `[..] -g -C debug-assertions [..]`
-",
- url = foo.url())));
-}
-
-#[test]
-fn build_only_bar_dependency() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "../bar"
- "#)
- .file("src/main.rs", r#"
- extern crate bar;
- fn main() {
- bar::baz()
- }
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- pub fn baz() {}
- "#);
- bar.build();
-
- assert_that(foo.cargo_process("rustc").arg("-v").arg("-p").arg("bar")
- .arg("--").arg("-C").arg("debug-assertions"),
- execs()
- .with_status(0)
- .with_stderr("\
-[COMPILING] bar v0.1.0 ([..])
-[RUNNING] `[..]--crate-name bar --crate-type lib [..] -C debug-assertions [..]`
-"));
-}
-
-#[test]
-fn fail_with_multiple_packages() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "../bar"
-
- [dependencies.baz]
- path = "../baz"
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#);
- foo.build();
-
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {
- if cfg!(flag = "1") { println!("Yeah from bar!"); }
- }
- "#);
- bar.build();
-
- let baz = project("baz")
- .file("Cargo.toml", r#"
- [package]
- name = "baz"
- version = "0.1.0"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {
- if cfg!(flag = "1") { println!("Yeah from baz!"); }
- }
- "#);
- baz.build();
-
- assert_that(foo.cargo("rustc").arg("-v").arg("-p").arg("bar")
- .arg("-p").arg("baz"),
- execs().with_status(1).with_stderr("\
-[ERROR] Invalid arguments.
-
-Usage:
- cargo rustc [options] [--] [<opts>...]"));
-}
-
-#[test]
-fn rustc_with_other_profile() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dev-dependencies]
- a = { path = "a" }
- "#)
- .file("src/main.rs", r#"
- #[cfg(test)] extern crate a;
-
- #[test]
- fn foo() {}
- "#)
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.1.0"
- authors = []
- "#)
- .file("a/src/lib.rs", "");
- foo.build();
-
- assert_that(foo.cargo("rustc").arg("--profile").arg("test"),
- execs().with_status(0));
-}
+++ /dev/null
-use std::path::MAIN_SEPARATOR as SEP;
-use support::{execs, project};
-use hamcrest::{assert_that};
-
-#[test]
-fn rustdoc_simple() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#" "#);
-
- assert_that(p.cargo_process("rustdoc").arg("-v"),
- execs()
- .with_status(0)
- .with_stderr(format!("\
-[DOCUMENTING] foo v0.0.1 ({url})
-[RUNNING] `rustdoc src{sep}lib.rs --crate-name foo \
- -o {dir}{sep}target{sep}doc \
- -L dependency={dir}{sep}target{sep}debug \
- -L dependency={dir}{sep}target{sep}debug{sep}deps`
-", sep = SEP,
- dir = p.root().display(), url = p.url())));
-}
-
-#[test]
-fn rustdoc_args() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#" "#);
-
- assert_that(p.cargo_process("rustdoc").arg("-v").arg("--").arg("--no-defaults"),
- execs()
- .with_status(0)
- .with_stderr(format!("\
-[DOCUMENTING] foo v0.0.1 ({url})
-[RUNNING] `rustdoc src{sep}lib.rs --crate-name foo \
- -o {dir}{sep}target{sep}doc \
- --no-defaults \
- -L dependency={dir}{sep}target{sep}debug \
- -L dependency={dir}{sep}target{sep}debug{sep}deps`
-", sep = SEP,
- dir = p.root().display(), url = p.url())));
-}
-
-
-
-#[test]
-fn rustdoc_foo_with_bar_dependency() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "../bar"
- "#)
- .file("src/lib.rs", r#"
- extern crate bar;
- pub fn foo() {}
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- pub fn baz() {}
- "#);
- bar.build();
-
- assert_that(foo.cargo_process("rustdoc").arg("-v").arg("--").arg("--no-defaults"),
- execs()
- .with_status(0)
- .with_stderr(format!("\
-[COMPILING] bar v0.0.1 ([..])
-[RUNNING] `rustc [..]bar{sep}src{sep}lib.rs [..]`
-[DOCUMENTING] foo v0.0.1 ({url})
-[RUNNING] `rustdoc src{sep}lib.rs --crate-name foo \
- -o {dir}{sep}target{sep}doc \
- --no-defaults \
- -L dependency={dir}{sep}target{sep}debug \
- -L dependency={dir}{sep}target{sep}debug{sep}deps \
- --extern [..]`
-", sep = SEP,
- dir = foo.root().display(), url = foo.url())));
-}
-
-#[test]
-fn rustdoc_only_bar_dependency() {
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.bar]
- path = "../bar"
- "#)
- .file("src/main.rs", r#"
- extern crate bar;
- fn main() {
- bar::baz()
- }
- "#);
- let bar = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- pub fn baz() {}
- "#);
- bar.build();
-
- assert_that(foo.cargo_process("rustdoc").arg("-v").arg("-p").arg("bar")
- .arg("--").arg("--no-defaults"),
- execs()
- .with_status(0)
- .with_stderr(format!("\
-[DOCUMENTING] bar v0.0.1 ([..])
-[RUNNING] `rustdoc [..]bar{sep}src{sep}lib.rs --crate-name bar \
- -o {dir}{sep}target{sep}doc \
- --no-defaults \
- -L dependency={dir}{sep}target{sep}debug{sep}deps \
- -L dependency={dir}{sep}target{sep}debug{sep}deps`
-", sep = SEP,
- dir = foo.root().display())));
-}
-
-
-#[test]
-fn rustdoc_same_name_err() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", r#"
- fn main() {}
- "#)
- .file("src/lib.rs", r#" "#);
-
- assert_that(p.cargo_process("rustdoc").arg("-v")
- .arg("--").arg("--no-defaults"),
- execs()
- .with_status(101)
- .with_stderr("[ERROR] cannot document a package where a library and a \
- binary have the same name. Consider renaming one \
- or marking the target as `doc = false`"));
-}
+++ /dev/null
-use std::fs::{self, File};
-use std::io::prelude::*;
-use std::path::PathBuf;
-
-use url::Url;
-
-use cargo::util::ProcessBuilder;
-use support::execs;
-use support::paths;
-use support::git::repo;
-
-use hamcrest::assert_that;
-
-fn registry_path() -> PathBuf { paths::root().join("registry") }
-fn registry() -> Url { Url::from_file_path(&*registry_path()).ok().unwrap() }
-fn api_path() -> PathBuf { paths::root().join("api") }
-fn api() -> Url { Url::from_file_path(&*api_path()).ok().unwrap() }
-
-fn setup() {
- let config = paths::root().join(".cargo/config");
- fs::create_dir_all(config.parent().unwrap()).unwrap();
- File::create(&config).unwrap().write_all(format!(r#"
- [registry]
- index = "{reg}"
- "#, reg = registry()).as_bytes()).unwrap();
- fs::create_dir_all(&api_path().join("api/v1")).unwrap();
-
- repo(®istry_path())
- .file("config.json", &format!(r#"{{
- "dl": "{0}",
- "api": "{0}"
- }}"#, api()))
- .build();
-}
-
-fn cargo_process(s: &str) -> ProcessBuilder {
- let mut b = ::cargo_process();
- b.arg(s);
- return b
-}
-
-#[test]
-fn simple() {
- setup();
-
- let contents = r#"{
- "crates": [{
- "created_at": "2014-11-16T20:17:35Z",
- "description": "Design by contract style assertions for Rust",
- "documentation": null,
- "downloads": 2,
- "homepage": null,
- "id": "hoare",
- "keywords": [],
- "license": null,
- "links": {
- "owners": "/api/v1/crates/hoare/owners",
- "reverse_dependencies": "/api/v1/crates/hoare/reverse_dependencies",
- "version_downloads": "/api/v1/crates/hoare/downloads",
- "versions": "/api/v1/crates/hoare/versions"
- },
- "max_version": "0.1.1",
- "name": "hoare",
- "repository": "https://github.com/nick29581/libhoare",
- "updated_at": "2014-11-20T21:49:21Z",
- "versions": null
- }],
- "meta": {
- "total": 1
- }
- }"#;
- let base = api_path().join("api/v1/crates");
-
- // Older versions of curl don't peel off query parameters when looking for
- // filenames, so just make both files.
- //
- // On windows, though, `?` is an invalid character, but we always build curl
- // from source there anyway!
- File::create(&base).unwrap().write_all(contents.as_bytes()).unwrap();
- if !cfg!(windows) {
- File::create(&base.with_file_name("crates?q=postgres&per_page=10")).unwrap()
- .write_all(contents.as_bytes()).unwrap();
- }
-
- assert_that(cargo_process("search").arg("postgres"),
- execs().with_status(0)
- .with_stderr("\
-[UPDATING] registry `[..]`")
- .with_stdout("\
-hoare (0.1.1) Design by contract style assertions for Rust"));
-}
-
-#[test]
-fn multiple_query_params() {
- setup();
-
- let contents = r#"{
- "crates": [{
- "created_at": "2014-11-16T20:17:35Z",
- "description": "Design by contract style assertions for Rust",
- "documentation": null,
- "downloads": 2,
- "homepage": null,
- "id": "hoare",
- "keywords": [],
- "license": null,
- "links": {
- "owners": "/api/v1/crates/hoare/owners",
- "reverse_dependencies": "/api/v1/crates/hoare/reverse_dependencies",
- "version_downloads": "/api/v1/crates/hoare/downloads",
- "versions": "/api/v1/crates/hoare/versions"
- },
- "max_version": "0.1.1",
- "name": "hoare",
- "repository": "https://github.com/nick29581/libhoare",
- "updated_at": "2014-11-20T21:49:21Z",
- "versions": null
- }],
- "meta": {
- "total": 1
- }
- }"#;
- let base = api_path().join("api/v1/crates");
-
- // Older versions of curl don't peel off query parameters when looking for
- // filenames, so just make both files.
- //
- // On windows, though, `?` is an invalid character, but we always build curl
- // from source there anyway!
- File::create(&base).unwrap().write_all(contents.as_bytes()).unwrap();
- if !cfg!(windows) {
- File::create(&base.with_file_name("crates?q=postgres+sql&per_page=10")).unwrap()
- .write_all(contents.as_bytes()).unwrap();
- }
-
- assert_that(cargo_process("search").arg("postgres").arg("sql"),
- execs().with_status(0)
- .with_stderr("\
-[UPDATING] registry `[..]`")
- .with_stdout("\
-hoare (0.1.1) Design by contract style assertions for Rust"));
-}
-
-#[test]
-fn help() {
- assert_that(cargo_process("search").arg("-h"),
- execs().with_status(0));
- assert_that(cargo_process("help").arg("search"),
- execs().with_status(0));
-}
+++ /dev/null
-use std::fs::File;
-use std::io::prelude::*;
-use std::str;
-
-use support::{project, execs, basic_bin_manifest, basic_lib_manifest};
-use support::paths::CargoPathExt;
-use hamcrest::{assert_that, existing_file, is_not};
-use cargo::util::process;
-
-#[test]
-fn cargo_test_simple() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", r#"
- fn hello() -> &'static str {
- "hello"
- }
-
- pub fn main() {
- println!("{}", hello())
- }
-
- #[test]
- fn test_hello() {
- assert_eq!(hello(), "hello")
- }"#);
-
- assert_that(p.cargo_process("build"), execs());
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("hello\n"));
-
- assert_that(p.cargo("test"),
- execs().with_stderr(format!("\
-[COMPILING] foo v0.5.0 ({})
-[RUNNING] target[..]foo-[..]", p.url()))
- .with_stdout("
-running 1 test
-test test_hello ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn cargo_test_release() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- authors = []
- version = "0.1.0"
-
- [dependencies]
- bar = { path = "bar" }
- "#)
- .file("src/lib.rs", r#"
- extern crate bar;
- pub fn foo() { bar::bar(); }
-
- #[test]
- fn test() { foo(); }
- "#)
- .file("tests/test.rs", r#"
- extern crate foo;
-
- #[test]
- fn test() { foo::foo(); }
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", "pub fn bar() {}");
-
- assert_that(p.cargo_process("test").arg("-v").arg("--release"),
- execs().with_stderr(format!("\
-[COMPILING] bar v0.0.1 ({dir}/bar)
-[RUNNING] [..] -C opt-level=3 [..]
-[COMPILING] foo v0.1.0 ({dir})
-[RUNNING] [..] -C opt-level=3 [..]
-[RUNNING] [..] -C opt-level=3 [..]
-[RUNNING] [..] -C opt-level=3 [..]
-[RUNNING] `[..]target[..]foo-[..]`
-[RUNNING] `[..]target[..]test-[..]`
-[DOCTEST] foo
-[RUNNING] `rustdoc --test [..]lib.rs[..]`", dir = p.url()))
- .with_stdout("
-running 1 test
-test test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn cargo_test_verbose() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", r#"
- fn main() {}
- #[test] fn test_hello() {}
- "#);
-
- assert_that(p.cargo_process("test").arg("-v").arg("hello"),
- execs().with_stderr(format!("\
-[COMPILING] foo v0.5.0 ({url})
-[RUNNING] `rustc src[..]foo.rs [..]`
-[RUNNING] `[..]target[..]foo-[..] hello`", url = p.url()))
- .with_stdout("
-running 1 test
-test test_hello ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn many_similar_names() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "
- pub fn foo() {}
- #[test] fn lib_test() {}
- ")
- .file("src/main.rs", "
- extern crate foo;
- fn main() {}
- #[test] fn bin_test() { foo::foo() }
- ")
- .file("tests/foo.rs", r#"
- extern crate foo;
- #[test] fn test_test() { foo::foo() }
- "#);
-
- let output = p.cargo_process("test").arg("-v").exec_with_output().unwrap();
- let output = str::from_utf8(&output.stdout).unwrap();
- assert!(output.contains("test bin_test"), "bin_test missing\n{}", output);
- assert!(output.contains("test lib_test"), "lib_test missing\n{}", output);
- assert!(output.contains("test test_test"), "test_test missing\n{}", output);
-}
-
-#[test]
-fn cargo_test_failing_test() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", r#"
- fn hello() -> &'static str {
- "hello"
- }
-
- pub fn main() {
- println!("{}", hello())
- }
-
- #[test]
- fn test_hello() {
- assert_eq!(hello(), "nope")
- }"#);
-
- assert_that(p.cargo_process("build"), execs());
- assert_that(&p.bin("foo"), existing_file());
-
- assert_that(process(&p.bin("foo")),
- execs().with_stdout("hello\n"));
-
- assert_that(p.cargo("test"),
- execs().with_stderr(format!("\
-[COMPILING] foo v0.5.0 ({url})
-[RUNNING] target[..]foo-[..]
-[ERROR] test failed", url = p.url()))
- .with_stdout_contains("
-running 1 test
-test test_hello ... FAILED
-
-failures:
-
----- test_hello stdout ----
-<tab>thread 'test_hello' panicked at 'assertion failed: \
- `(left == right)` (left: \
- `\"hello\"`, right: `\"nope\"`)', src[..]foo.rs:12
-")
- .with_stdout_contains("\
-failures:
- test_hello
-
-test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
-")
- .with_status(101));
-}
-
-#[test]
-fn test_with_lib_dep() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [[bin]]
- name = "baz"
- path = "src/main.rs"
- "#)
- .file("src/lib.rs", r#"
- ///
- /// ```rust
- /// extern crate foo;
- /// fn main() {
- /// println!("{:?}", foo::foo());
- /// }
- /// ```
- ///
- pub fn foo(){}
- #[test] fn lib_test() {}
- "#)
- .file("src/main.rs", "
- extern crate foo;
-
- fn main() {}
-
- #[test]
- fn bin_test() {}
- ");
-
- assert_that(p.cargo_process("test"),
- execs().with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({})
-[RUNNING] target[..]baz-[..]
-[RUNNING] target[..]foo[..]
-[DOCTEST] foo", p.url()))
- .with_stdout("
-running 1 test
-test bin_test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test lib_test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test foo_0 ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"))
-}
-
-#[test]
-fn test_with_deep_lib_dep() {
- let p = project("bar")
- .file("Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [dependencies.foo]
- path = "../foo"
- "#)
- .file("src/lib.rs", "
- extern crate foo;
- /// ```
- /// bar::bar();
- /// ```
- pub fn bar() {}
-
- #[test]
- fn bar_test() {
- foo::foo();
- }
- ");
- let p2 = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "
- pub fn foo() {}
-
- #[test]
- fn foo_test() {}
- ");
-
- p2.build();
- assert_that(p.cargo_process("test"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ([..])
-[COMPILING] bar v0.0.1 ({dir})
-[RUNNING] target[..]
-[DOCTEST] bar", dir = p.url()))
- .with_stdout("
-running 1 test
-test bar_test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test bar_0 ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn external_test_explicit() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [[test]]
- name = "test"
- path = "src/test.rs"
- "#)
- .file("src/lib.rs", r#"
- pub fn get_hello() -> &'static str { "Hello" }
-
- #[test]
- fn internal_test() {}
- "#)
- .file("src/test.rs", r#"
- extern crate foo;
-
- #[test]
- fn external_test() { assert_eq!(foo::get_hello(), "Hello") }
- "#);
-
- assert_that(p.cargo_process("test"),
- execs().with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({})
-[RUNNING] target[..]foo-[..]
-[RUNNING] target[..]test-[..]
-[DOCTEST] foo", p.url()))
- .with_stdout("
-running 1 test
-test internal_test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test external_test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"))
-}
-
-#[test]
-fn external_test_implicit() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- pub fn get_hello() -> &'static str { "Hello" }
-
- #[test]
- fn internal_test() {}
- "#)
- .file("tests/external.rs", r#"
- extern crate foo;
-
- #[test]
- fn external_test() { assert_eq!(foo::get_hello(), "Hello") }
- "#);
-
- assert_that(p.cargo_process("test"),
- execs().with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({})
-[RUNNING] target[..]external-[..]
-[RUNNING] target[..]foo-[..]
-[DOCTEST] foo", p.url()))
- .with_stdout("
-running 1 test
-test external_test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test internal_test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"))
-}
-
-#[test]
-fn dont_run_examples() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- "#)
- .file("examples/dont-run-me-i-will-fail.rs", r#"
- fn main() { panic!("Examples should not be run by 'cargo test'"); }
- "#);
- assert_that(p.cargo_process("test"),
- execs().with_status(0));
-}
-
-#[test]
-fn pass_through_command_line() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "
- #[test] fn foo() {}
- #[test] fn bar() {}
- ");
-
- assert_that(p.cargo_process("test").arg("bar"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] target[..]foo-[..]
-[DOCTEST] foo", dir = p.url()))
- .with_stdout("
-running 1 test
-test bar ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-
- assert_that(p.cargo("test").arg("foo"),
- execs().with_status(0)
- .with_stderr("\
-[RUNNING] target[..]foo-[..]
-[DOCTEST] foo")
- .with_stdout("
-running 1 test
-test foo ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-// Regression test for running cargo-test twice with
-// tests in an rlib
-#[test]
-fn cargo_test_twice() {
- let p = project("test_twice")
- .file("Cargo.toml", &basic_lib_manifest("test_twice"))
- .file("src/test_twice.rs", r#"
- #![crate_type = "rlib"]
-
- #[test]
- fn dummy_test() { }
- "#);
-
- p.cargo_process("build");
-
- for _ in 0..2 {
- assert_that(p.cargo("test"),
- execs().with_status(0));
- }
-}
-
-#[test]
-fn lib_bin_same_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo"
- [[bin]]
- name = "foo"
- "#)
- .file("src/lib.rs", "
- #[test] fn lib_test() {}
- ")
- .file("src/main.rs", "
- extern crate foo;
-
- #[test]
- fn bin_test() {}
- ");
-
- assert_that(p.cargo_process("test"),
- execs().with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({})
-[RUNNING] target[..]foo-[..]
-[RUNNING] target[..]foo-[..]
-[DOCTEST] foo", p.url()))
- .with_stdout("
-running 1 test
-test [..] ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test [..] ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"))
-}
-
-#[test]
-fn lib_with_standard_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "syntax"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "
- /// ```
- /// syntax::foo();
- /// ```
- pub fn foo() {}
-
- #[test]
- fn foo_test() {}
- ")
- .file("tests/test.rs", "
- extern crate syntax;
-
- #[test]
- fn test() { syntax::foo() }
- ");
-
- assert_that(p.cargo_process("test"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] syntax v0.0.1 ({dir})
-[RUNNING] target[..]syntax-[..]
-[RUNNING] target[..]test-[..]
-[DOCTEST] syntax", dir = p.url()))
- .with_stdout("
-running 1 test
-test foo_test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test foo_0 ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn lib_with_standard_name2() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "syntax"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "syntax"
- test = false
- doctest = false
- "#)
- .file("src/lib.rs", "
- pub fn foo() {}
- ")
- .file("src/main.rs", "
- extern crate syntax;
-
- fn main() {}
-
- #[test]
- fn test() { syntax::foo() }
- ");
-
- assert_that(p.cargo_process("test"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] syntax v0.0.1 ({dir})
-[RUNNING] target[..]syntax-[..]", dir = p.url()))
- .with_stdout("
-running 1 test
-test test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn lib_without_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "syntax"
- version = "0.0.1"
- authors = []
-
- [lib]
- test = false
- doctest = false
- "#)
- .file("src/lib.rs", "
- pub fn foo() {}
- ")
- .file("src/main.rs", "
- extern crate syntax;
-
- fn main() {}
-
- #[test]
- fn test() { syntax::foo() }
- ");
-
- assert_that(p.cargo_process("test"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] syntax v0.0.1 ({dir})
-[RUNNING] target[..]syntax-[..]", dir = p.url()))
- .with_stdout("
-running 1 test
-test test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn bin_without_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "syntax"
- version = "0.0.1"
- authors = []
-
- [lib]
- test = false
- doctest = false
-
- [[bin]]
- path = "src/main.rs"
- "#)
- .file("src/lib.rs", "
- pub fn foo() {}
- ")
- .file("src/main.rs", "
- extern crate syntax;
-
- fn main() {}
-
- #[test]
- fn test() { syntax::foo() }
- ");
-
- assert_that(p.cargo_process("test"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- binary target bin.name is required"));
-}
-
-#[test]
-fn bench_without_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "syntax"
- version = "0.0.1"
- authors = []
-
- [lib]
- test = false
- doctest = false
-
- [[bench]]
- path = "src/bench.rs"
- "#)
- .file("src/lib.rs", "
- pub fn foo() {}
- ")
- .file("src/main.rs", "
- extern crate syntax;
-
- fn main() {}
-
- #[test]
- fn test() { syntax::foo() }
- ")
- .file("src/bench.rs", "
- #![feature(test)]
- extern crate syntax;
- extern crate test;
-
- #[bench]
- fn external_bench(_b: &mut test::Bencher) {}
- ");
-
- assert_that(p.cargo_process("test"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- bench target bench.name is required"));
-}
-
-#[test]
-fn test_without_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "syntax"
- version = "0.0.1"
- authors = []
-
- [lib]
- test = false
- doctest = false
-
- [[test]]
- path = "src/test.rs"
- "#)
- .file("src/lib.rs", r#"
- pub fn foo() {}
- pub fn get_hello() -> &'static str { "Hello" }
- "#)
- .file("src/main.rs", "
- extern crate syntax;
-
- fn main() {}
-
- #[test]
- fn test() { syntax::foo() }
- ")
- .file("src/test.rs", r#"
- extern crate syntax;
-
- #[test]
- fn external_test() { assert_eq!(syntax::get_hello(), "Hello") }
- "#);
-
- assert_that(p.cargo_process("test"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- test target test.name is required"));
-}
-
-#[test]
-fn example_without_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "syntax"
- version = "0.0.1"
- authors = []
-
- [lib]
- test = false
- doctest = false
-
- [[example]]
- path = "examples/example.rs"
- "#)
- .file("src/lib.rs", "
- pub fn foo() {}
- ")
- .file("src/main.rs", "
- extern crate syntax;
-
- fn main() {}
-
- #[test]
- fn test() { syntax::foo() }
- ")
- .file("examples/example.rs", r#"
- extern crate syntax;
-
- fn main() {
- println!("example1");
- }
- "#);
-
- assert_that(p.cargo_process("test"),
- execs().with_status(101)
- .with_stderr("\
-[ERROR] failed to parse manifest at `[..]`
-
-Caused by:
- example target example.name is required"));
-}
-
-#[test]
-fn bin_there_for_integration() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/main.rs", "
- fn main() { std::process::exit(101); }
- #[test] fn main_test() {}
- ")
- .file("tests/foo.rs", r#"
- use std::process::Command;
- #[test]
- fn test_test() {
- let status = Command::new("target/debug/foo").status().unwrap();
- assert_eq!(status.code(), Some(101));
- }
- "#);
-
- let output = p.cargo_process("test").arg("-v").exec_with_output().unwrap();
- let output = str::from_utf8(&output.stdout).unwrap();
- assert!(output.contains("main_test ... ok"), "no main_test\n{}", output);
- assert!(output.contains("test_test ... ok"), "no test_test\n{}", output);
-}
-
-#[test]
-fn test_dylib() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo"
- crate_type = ["dylib"]
-
- [dependencies.bar]
- path = "bar"
- "#)
- .file("src/lib.rs", r#"
- extern crate bar as the_bar;
-
- pub fn bar() { the_bar::baz(); }
-
- #[test]
- fn foo() { bar(); }
- "#)
- .file("tests/test.rs", r#"
- extern crate foo as the_foo;
-
- #[test]
- fn foo() { the_foo::bar(); }
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "bar"
- crate_type = ["dylib"]
- "#)
- .file("bar/src/lib.rs", "
- pub fn baz() {}
- ");
-
- assert_that(p.cargo_process("test"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] bar v0.0.1 ({dir}/bar)
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] target[..]foo-[..]
-[RUNNING] target[..]test-[..]", dir = p.url()))
- .with_stdout("
-running 1 test
-test foo ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test foo ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
- p.root().move_into_the_past().unwrap();
- assert_that(p.cargo("test"),
- execs().with_status(0)
- .with_stderr("\
-[RUNNING] target[..]foo-[..]
-[RUNNING] target[..]test-[..]")
- .with_stdout("
-running 1 test
-test foo ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test foo ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-
-}
-
-#[test]
-fn test_twice_with_build_cmd() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- "#)
- .file("build.rs", "fn main() {}")
- .file("src/lib.rs", "
- #[test]
- fn foo() {}
- ");
-
- assert_that(p.cargo_process("test"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] target[..]foo-[..]
-[DOCTEST] foo", dir = p.url()))
- .with_stdout("
-running 1 test
-test foo ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-
- assert_that(p.cargo("test"),
- execs().with_status(0)
- .with_stderr("\
-[RUNNING] target[..]foo-[..]
-[DOCTEST] foo")
- .with_stdout("
-running 1 test
-test foo ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn test_then_build() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "
- #[test]
- fn foo() {}
- ");
-
- assert_that(p.cargo_process("test"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] target[..]foo-[..]
-[DOCTEST] foo", dir = p.url()))
- .with_stdout("
-running 1 test
-test foo ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-
- assert_that(p.cargo("build"),
- execs().with_status(0)
- .with_stdout(""));
-}
-
-#[test]
-fn test_no_run() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "
- #[test]
- fn foo() { panic!() }
- ");
-
- assert_that(p.cargo_process("test").arg("--no-run"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-",
- dir = p.url())));
-}
-
-#[test]
-fn test_run_specific_bin_target() {
- let prj = project("foo")
- .file("Cargo.toml" , r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [[bin]]
- name="bin1"
- path="src/bin1.rs"
-
- [[bin]]
- name="bin2"
- path="src/bin2.rs"
- "#)
- .file("src/bin1.rs", "#[test] fn test1() { }")
- .file("src/bin2.rs", "#[test] fn test2() { }");
-
- assert_that(prj.cargo_process("test").arg("--bin").arg("bin2"),
- execs().with_status(0)
- .with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] target[..]bin2-[..]", dir = prj.url()))
- .with_stdout("
-running 1 test
-test test2 ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn test_run_specific_test_target() {
- let prj = project("foo")
- .file("Cargo.toml" , r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/bin/a.rs", "fn main() { }")
- .file("src/bin/b.rs", "#[test] fn test_b() { } fn main() { }")
- .file("tests/a.rs", "#[test] fn test_a() { }")
- .file("tests/b.rs", "#[test] fn test_b() { }");
-
- assert_that(prj.cargo_process("test").arg("--test").arg("b"),
- execs().with_status(0)
- .with_stderr(format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] target[..]b-[..]", dir = prj.url()))
- .with_stdout("
-running 1 test
-test test_b ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn test_no_harness() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [[bin]]
- name = "foo"
- test = false
-
- [[test]]
- name = "bar"
- path = "foo.rs"
- harness = false
- "#)
- .file("src/main.rs", "fn main() {}")
- .file("foo.rs", "fn main() {}");
-
- assert_that(p.cargo_process("test").arg("--").arg("--nocapture"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] target[..]bar-[..]
-",
- dir = p.url())));
-}
-
-#[test]
-fn selective_testing() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.d1]
- path = "d1"
- [dependencies.d2]
- path = "d2"
-
- [lib]
- name = "foo"
- doctest = false
- "#)
- .file("src/lib.rs", "")
- .file("d1/Cargo.toml", r#"
- [package]
- name = "d1"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "d1"
- doctest = false
- "#)
- .file("d1/src/lib.rs", "")
- .file("d1/src/main.rs", "extern crate d1; fn main() {}")
- .file("d2/Cargo.toml", r#"
- [package]
- name = "d2"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "d2"
- doctest = false
- "#)
- .file("d2/src/lib.rs", "")
- .file("d2/src/main.rs", "extern crate d2; fn main() {}");
- p.build();
-
- println!("d1");
- assert_that(p.cargo("test").arg("-p").arg("d1"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] d1 v0.0.1 ({dir}/d1)
-[RUNNING] target[..]d1-[..]
-[RUNNING] target[..]d1-[..]", dir = p.url()))
- .with_stdout("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-
- println!("d2");
- assert_that(p.cargo("test").arg("-p").arg("d2"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] d2 v0.0.1 ({dir}/d2)
-[RUNNING] target[..]d2-[..]
-[RUNNING] target[..]d2-[..]", dir = p.url()))
- .with_stdout("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-
- println!("whole");
- assert_that(p.cargo("test"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] target[..]foo-[..]", dir = p.url()))
- .with_stdout("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn almost_cyclic_but_not_quite() {
- let p = project("a")
- .file("Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [dev-dependencies.b]
- path = "b"
- [dev-dependencies.c]
- path = "c"
- "#)
- .file("src/lib.rs", r#"
- #[cfg(test)] extern crate b;
- #[cfg(test)] extern crate c;
- "#)
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.0.1"
- authors = []
-
- [dependencies.a]
- path = ".."
- "#)
- .file("b/src/lib.rs", r#"
- extern crate a;
- "#)
- .file("c/Cargo.toml", r#"
- [package]
- name = "c"
- version = "0.0.1"
- authors = []
- "#)
- .file("c/src/lib.rs", "");
-
- assert_that(p.cargo_process("build"), execs().with_status(0));
- assert_that(p.cargo("test"),
- execs().with_status(0));
-}
-
-#[test]
-fn build_then_selective_test() {
- let p = project("a")
- .file("Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
-
- [dependencies.b]
- path = "b"
- "#)
- .file("src/lib.rs", "extern crate b;")
- .file("src/main.rs", "extern crate b; extern crate a; fn main() {}")
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.0.1"
- authors = []
- "#)
- .file("b/src/lib.rs", "");
-
- assert_that(p.cargo_process("build"), execs().with_status(0));
- p.root().move_into_the_past().unwrap();
- assert_that(p.cargo("test").arg("-p").arg("b"),
- execs().with_status(0));
-}
-
-#[test]
-fn example_dev_dep() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dev-dependencies.bar]
- path = "bar"
- "#)
- .file("src/lib.rs", r#"
- "#)
- .file("examples/e1.rs", r#"
- extern crate bar;
- fn main() { }
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", r#"
- // make sure this file takes awhile to compile
- macro_rules! f0( () => (1) );
- macro_rules! f1( () => ({(f0!()) + (f0!())}) );
- macro_rules! f2( () => ({(f1!()) + (f1!())}) );
- macro_rules! f3( () => ({(f2!()) + (f2!())}) );
- macro_rules! f4( () => ({(f3!()) + (f3!())}) );
- macro_rules! f5( () => ({(f4!()) + (f4!())}) );
- macro_rules! f6( () => ({(f5!()) + (f5!())}) );
- macro_rules! f7( () => ({(f6!()) + (f6!())}) );
- macro_rules! f8( () => ({(f7!()) + (f7!())}) );
- pub fn bar() {
- f8!();
- }
- "#);
- assert_that(p.cargo_process("test"),
- execs().with_status(0));
- assert_that(p.cargo("run")
- .arg("--example").arg("e1").arg("--release").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn selective_testing_with_docs() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.d1]
- path = "d1"
- "#)
- .file("src/lib.rs", r#"
- /// ```
- /// not valid rust
- /// ```
- pub fn foo() {}
- "#)
- .file("d1/Cargo.toml", r#"
- [package]
- name = "d1"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "d1"
- path = "d1.rs"
- "#)
- .file("d1/d1.rs", "");
- p.build();
-
- assert_that(p.cargo("test").arg("-p").arg("d1"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] d1 v0.0.1 ({dir}/d1)
-[RUNNING] target[..]deps[..]d1[..]
-[DOCTEST] d1", dir = p.url()))
- .with_stdout("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn example_bin_same_name() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/bin/foo.rs", r#"fn main() { println!("bin"); }"#)
- .file("examples/foo.rs", r#"fn main() { println!("example"); }"#);
-
- assert_that(p.cargo_process("test").arg("--no-run").arg("-v"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({dir})
-[RUNNING] `rustc [..]`
-[RUNNING] `rustc [..]`
-", dir = p.url())));
-
- assert_that(&p.bin("foo"), is_not(existing_file()));
- assert_that(&p.bin("examples/foo"), existing_file());
-
- assert_that(p.process(&p.bin("examples/foo")),
- execs().with_status(0).with_stdout("example\n"));
-
- assert_that(p.cargo("run"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] foo v0.0.1 ([..])
-[RUNNING] [..]")
- .with_stdout("\
-bin
-"));
- assert_that(&p.bin("foo"), existing_file());
-}
-
-#[test]
-fn test_with_example_twice() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/bin/foo.rs", r#"fn main() { println!("bin"); }"#)
- .file("examples/foo.rs", r#"fn main() { println!("example"); }"#);
-
- println!("first");
- assert_that(p.cargo_process("test").arg("-v"),
- execs().with_status(0));
- assert_that(&p.bin("examples/foo"), existing_file());
- println!("second");
- assert_that(p.cargo("test").arg("-v"),
- execs().with_status(0));
- assert_that(&p.bin("examples/foo"), existing_file());
-}
-
-#[test]
-fn example_with_dev_dep() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo"
- test = false
- doctest = false
-
- [dev-dependencies.a]
- path = "a"
- "#)
- .file("src/lib.rs", "")
- .file("examples/ex.rs", "extern crate a; fn main() {}")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
- "#)
- .file("a/src/lib.rs", "");
-
- assert_that(p.cargo_process("test").arg("-v"),
- execs().with_status(0)
- .with_stderr("\
-[..]
-[..]
-[..]
-[..]
-[RUNNING] `rustc [..] --crate-name ex [..] --extern a=[..]`
-"));
-}
-
-#[test]
-fn bin_is_preserved() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file("src/main.rs", "fn main() {}");
-
- assert_that(p.cargo_process("build").arg("-v"),
- execs().with_status(0));
- assert_that(&p.bin("foo"), existing_file());
-
- println!("testing");
- assert_that(p.cargo("test").arg("-v"),
- execs().with_status(0));
- assert_that(&p.bin("foo"), existing_file());
-}
-
-#[test]
-fn bad_example() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "");
-
- assert_that(p.cargo_process("run").arg("--example").arg("foo"),
- execs().with_status(101).with_stderr("\
-[ERROR] no example target named `foo`
-"));
- assert_that(p.cargo_process("run").arg("--bin").arg("foo"),
- execs().with_status(101).with_stderr("\
-[ERROR] no bin target named `foo`
-"));
-}
-
-#[test]
-fn doctest_feature() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- [features]
- bar = []
- "#)
- .file("src/lib.rs", r#"
- /// ```rust
- /// assert_eq!(foo::foo(), 1);
- /// ```
- #[cfg(feature = "bar")]
- pub fn foo() -> i32 { 1 }
- "#);
-
- assert_that(p.cargo_process("test").arg("--features").arg("bar"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] foo [..]
-[RUNNING] target[..]foo[..]
-[DOCTEST] foo")
- .with_stdout("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test foo_0 ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"))
-}
-
-#[test]
-fn dashes_to_underscores() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo-bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- /// ```
- /// assert_eq!(foo_bar::foo(), 1);
- /// ```
- pub fn foo() -> i32 { 1 }
- "#);
-
- assert_that(p.cargo_process("test").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn doctest_dev_dep() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dev-dependencies]
- b = { path = "b" }
- "#)
- .file("src/lib.rs", r#"
- /// ```
- /// extern crate b;
- /// ```
- pub fn foo() {}
- "#)
- .file("b/Cargo.toml", r#"
- [package]
- name = "b"
- version = "0.0.1"
- authors = []
- "#)
- .file("b/src/lib.rs", "");
-
- assert_that(p.cargo_process("test").arg("-v"),
- execs().with_status(0));
-}
-
-#[test]
-fn filter_no_doc_tests() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- /// ```
- /// extern crate b;
- /// ```
- pub fn foo() {}
- "#)
- .file("tests/foo.rs", "");
-
- assert_that(p.cargo_process("test").arg("--test=foo"),
- execs().with_stderr("\
-[COMPILING] foo v0.0.1 ([..])
-[RUNNING] target[..]debug[..]foo[..]")
- .with_stdout("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn dylib_doctest() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo"
- crate-type = ["rlib", "dylib"]
- test = false
- "#)
- .file("src/lib.rs", r#"
- /// ```
- /// foo::foo();
- /// ```
- pub fn foo() {}
- "#);
-
- assert_that(p.cargo_process("test"),
- execs().with_stderr("\
-[COMPILING] foo v0.0.1 ([..])
-[DOCTEST] foo")
- .with_stdout("
-running 1 test
-test foo_0 ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"));
-}
-
-#[test]
-fn dylib_doctest2() {
- // can't doctest dylibs as they're statically linked together
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo"
- crate-type = ["dylib"]
- test = false
- "#)
- .file("src/lib.rs", r#"
- /// ```
- /// foo::foo();
- /// ```
- pub fn foo() {}
- "#);
-
- assert_that(p.cargo_process("test"),
- execs().with_stdout(""));
-}
-
-#[test]
-fn cyclic_dev_dep_doc_test() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dev-dependencies]
- bar = { path = "bar" }
- "#)
- .file("src/lib.rs", r#"
- //! ```
- //! extern crate bar;
- //! ```
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- foo = { path = ".." }
- "#)
- .file("bar/src/lib.rs", r#"
- extern crate foo;
- "#);
- assert_that(p.cargo_process("test"),
- execs().with_stderr("\
-[COMPILING] foo v0.0.1 ([..])
-[COMPILING] bar v0.0.1 ([..])
-[RUNNING] target[..]foo[..]
-[DOCTEST] foo")
- .with_stdout("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test _0 ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"))
-}
-
-#[test]
-fn dev_dep_with_build_script() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dev-dependencies]
- bar = { path = "bar" }
- "#)
- .file("src/lib.rs", "")
- .file("examples/foo.rs", "fn main() {}")
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- build = "build.rs"
- "#)
- .file("bar/src/lib.rs", "")
- .file("bar/build.rs", "fn main() {}");
- assert_that(p.cargo_process("test"),
- execs().with_status(0));
-}
-
-#[test]
-fn no_fail_fast() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- pub fn add_one(x: i32) -> i32{
- x + 1
- }
-
- /// ```rust
- /// use foo::sub_one;
- /// assert_eq!(sub_one(101), 100);
- /// ```
- pub fn sub_one(x: i32) -> i32{
- x - 1
- }
- "#)
- .file("tests/test_add_one.rs", r#"
- extern crate foo;
- use foo::*;
-
- #[test]
- fn add_one_test() {
- assert_eq!(add_one(1), 2);
- }
-
- #[test]
- fn fail_add_one_test() {
- assert_eq!(add_one(1), 1);
- }
- "#)
- .file("tests/test_sub_one.rs", r#"
- extern crate foo;
- use foo::*;
-
- #[test]
- fn sub_one_test() {
- assert_eq!(sub_one(1), 0);
- }
- "#);
- assert_that(p.cargo_process("test").arg("--no-fail-fast"),
- execs().with_status(101)
- .with_stderr_contains("\
-[COMPILING] foo v0.0.1 ([..])
-[RUNNING] target[..]foo[..]
-[RUNNING] target[..]test_add_one[..]")
- .with_stdout_contains("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-")
- .with_stderr_contains("\
-[RUNNING] target[..]test_sub_one[..]
-[DOCTEST] foo")
- .with_stdout_contains("\
-test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test sub_one_test ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test sub_one_0 ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
-
-"))
-}
-
-#[test]
-fn test_multiple_packages() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies.d1]
- path = "d1"
- [dependencies.d2]
- path = "d2"
-
- [lib]
- name = "foo"
- doctest = false
- "#)
- .file("src/lib.rs", "")
- .file("d1/Cargo.toml", r#"
- [package]
- name = "d1"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "d1"
- doctest = false
- "#)
- .file("d1/src/lib.rs", "")
- .file("d2/Cargo.toml", r#"
- [package]
- name = "d2"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "d2"
- doctest = false
- "#)
- .file("d2/src/lib.rs", "");
- p.build();
-
- assert_that(p.cargo("test").arg("-p").arg("d1").arg("-p").arg("d2"),
- execs().with_status(0)
- .with_stderr_contains("\
-[RUNNING] target[..]debug[..]d1-[..]")
- .with_stdout_contains("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-")
- .with_stderr_contains("\
-[RUNNING] target[..]debug[..]d2-[..]")
- .with_stdout_contains("
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-"));
-}
-
-#[test]
-fn bin_does_not_rebuild_tests() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", "")
- .file("src/main.rs", "fn main() {}")
- .file("tests/foo.rs", "");
- p.build();
-
- assert_that(p.cargo("test").arg("-v"),
- execs().with_status(0));
-
- ::sleep_ms(1000);
- File::create(&p.root().join("src/main.rs")).unwrap()
- .write_all(b"fn main() { 3; }").unwrap();
-
- assert_that(p.cargo("test").arg("-v").arg("--no-run"),
- execs().with_status(0)
- .with_stderr("\
-[COMPILING] foo v0.0.1 ([..])
-[RUNNING] `rustc src[..]main.rs [..]`
-[RUNNING] `rustc src[..]main.rs [..]`
-"));
-}
-
-#[test]
-fn selective_test_wonky_profile() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [profile.release]
- opt-level = 2
-
- [dependencies]
- a = { path = "a" }
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
- "#)
- .file("a/src/lib.rs", "");
- p.build();
-
- assert_that(p.cargo("test").arg("-v").arg("--no-run").arg("--release")
- .arg("-p").arg("foo").arg("-p").arg("a"),
- execs().with_status(0));
-}
-
-#[test]
-fn selective_test_optional_dep() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- a = { path = "a", optional = true }
- "#)
- .file("src/lib.rs", "")
- .file("a/Cargo.toml", r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
- "#)
- .file("a/src/lib.rs", "");
- p.build();
-
- assert_that(p.cargo("test").arg("-v").arg("--no-run")
- .arg("--features").arg("a").arg("-p").arg("a"),
- execs().with_status(0).with_stderr("\
-[COMPILING] a v0.0.1 ([..])
-[RUNNING] `rustc a[..]src[..]lib.rs [..]`
-[RUNNING] `rustc a[..]src[..]lib.rs [..]`
-"));
-}
-
-#[test]
-fn only_test_docs() {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
- "#)
- .file("src/lib.rs", r#"
- #[test]
- fn foo() {
- let a: u32 = "hello";
- }
-
- /// ```
- /// println!("ok");
- /// ```
- pub fn bar() {
- }
- "#)
- .file("tests/foo.rs", "this is not rust");
- p.build();
-
- assert_that(p.cargo("test").arg("--doc"),
- execs().with_status(0)
- .with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ([..])
-[DOCTEST] foo"))
- .with_stdout("
-running 1 test
-test bar_0 ... ok
-
-test result: ok.[..]
-
-"));
-}
-
-#[test]
-fn test_panic_abort_with_dep() {
- if !::is_nightly() {
- return
- }
- let p = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [dependencies]
- bar = { path = "bar" }
-
- [profile.dev]
- panic = 'abort'
- "#)
- .file("src/lib.rs", r#"
- extern crate bar;
-
- #[test]
- fn foo() {}
- "#)
- .file("bar/Cargo.toml", r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#)
- .file("bar/src/lib.rs", "");
- assert_that(p.cargo_process("test").arg("-v"),
- execs().with_status(0));
-}
+++ /dev/null
-use support::{path2url, project, execs};
-use hamcrest::assert_that;
-
-#[test]
-fn pathless_tools() {
- let target = ::rustc_host();
-
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo"
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", &format!(r#"
- [target.{}]
- ar = "nonexistent-ar"
- linker = "nonexistent-linker"
- "#, target));
-
- assert_that(foo.cargo_process("build").arg("--verbose"),
- execs().with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({url})
-[RUNNING] `rustc [..] -C ar=nonexistent-ar -C linker=nonexistent-linker [..]`
-", url = foo.url())))
-}
-
-#[test]
-fn absolute_tools() {
- let target = ::rustc_host();
-
- // Escaped as they appear within a TOML config file
- let config = if cfg!(windows) {
- (r#"C:\\bogus\\nonexistent-ar"#, r#"C:\\bogus\\nonexistent-linker"#)
- } else {
- (r#"/bogus/nonexistent-ar"#, r#"/bogus/nonexistent-linker"#)
- };
-
- let foo = project("foo")
- .file("Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo"
- "#)
- .file("src/lib.rs", "")
- .file(".cargo/config", &format!(r#"
- [target.{target}]
- ar = "{ar}"
- linker = "{linker}"
- "#, target = target, ar = config.0, linker = config.1));
-
- let output = if cfg!(windows) {
- (r#"C:\bogus\nonexistent-ar"#, r#"C:\bogus\nonexistent-linker"#)
- } else {
- (r#"/bogus/nonexistent-ar"#, r#"/bogus/nonexistent-linker"#)
- };
-
- assert_that(foo.cargo_process("build").arg("--verbose"),
- execs().with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({url})
-[RUNNING] `rustc [..] -C ar={ar} -C linker={linker} [..]`
-", url = foo.url(), ar = output.0, linker = output.1)))
-}
-
-#[test]
-fn relative_tools() {
- let target = ::rustc_host();
-
- // Escaped as they appear within a TOML config file
- let config = if cfg!(windows) {
- (r#".\\nonexistent-ar"#, r#".\\tools\\nonexistent-linker"#)
- } else {
- (r#"./nonexistent-ar"#, r#"./tools/nonexistent-linker"#)
- };
-
- // Funky directory structure to test that relative tool paths are made absolute
- // by reference to the `.cargo/..` directory and not to (for example) the CWD.
- let origin = project("origin")
- .file("foo/Cargo.toml", r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lib]
- name = "foo"
- "#)
- .file("foo/src/lib.rs", "")
- .file(".cargo/config", &format!(r#"
- [target.{target}]
- ar = "{ar}"
- linker = "{linker}"
- "#, target = target, ar = config.0, linker = config.1));
-
- let foo_path = origin.root().join("foo");
- let foo_url = path2url(foo_path.clone());
- let prefix = origin.root().into_os_string().into_string().unwrap();
- let output = if cfg!(windows) {
- (format!(r#"{}\.\nonexistent-ar"#, prefix),
- format!(r#"{}\.\tools\nonexistent-linker"#, prefix))
- } else {
- (format!(r#"{}/./nonexistent-ar"#, prefix),
- format!(r#"{}/./tools/nonexistent-linker"#, prefix))
- };
-
- assert_that(origin.cargo_process("build").cwd(foo_path).arg("--verbose"),
- execs().with_stderr(&format!("\
-[COMPILING] foo v0.0.1 ({url})
-[RUNNING] `rustc [..] -C ar={ar} -C linker={linker} [..]`
-", url = foo_url, ar = output.0, linker = output.1)))
-}
+++ /dev/null
-use support::{project, execs, main_file, basic_bin_manifest};
-use hamcrest::{assert_that};
-
-fn verify_project_success_output() -> String {
- r#"{"success":"true"}"#.into()
-}
-
-#[test]
-fn cargo_verify_project_path_to_cargo_toml_relative() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("verify-project")
- .arg("--manifest-path").arg("foo/Cargo.toml")
- .cwd(p.root().parent().unwrap()),
- execs().with_status(0)
- .with_stdout(verify_project_success_output()));
-}
-
-#[test]
-fn cargo_verify_project_path_to_cargo_toml_absolute() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("verify-project")
- .arg("--manifest-path").arg(p.root().join("Cargo.toml"))
- .cwd(p.root().parent().unwrap()),
- execs().with_status(0)
- .with_stdout(verify_project_success_output()));
-}
-
-#[test]
-fn cargo_verify_project_cwd() {
- let p = project("foo")
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
-
- assert_that(p.cargo_process("verify-project")
- .cwd(p.root()),
- execs().with_status(0)
- .with_stdout(verify_project_success_output()));
-}
+++ /dev/null
-use support::{project, execs};
-use hamcrest::assert_that;
-use cargo;
-
-#[test]
-fn simple() {
- let p = project("foo");
-
- assert_that(p.cargo_process("version"),
- execs().with_status(0).with_stdout(&format!("{}\n",
- cargo::version())));
-
- assert_that(p.cargo_process("--version"),
- execs().with_status(0).with_stdout(&format!("{}\n",
- cargo::version())));
-
-}
-
-#[derive(RustcDecodable)]
-struct FooFlags {
- flag_version: bool,
-}
-
-fn real_main(flags: FooFlags, _config: &cargo::Config) ->
- cargo::CliResult<Option<String>> {
- if flags.flag_version {
- Ok(Some("foo <version>".to_string()))
- } else {
- Ok(None)
- }
-}
-
-#[test]
-fn subcommand_with_version_using_exec_main_without_stdin() {
- let usage = "
-Usage: cargo foo [--version]
-
-Options:
- -V, --version Print version info
-";
- let args: Vec<String> = vec!["cargo", "foo", "--version"]
- .into_iter().map(|s| s.to_string()).collect();
- let result = cargo::call_main_without_stdin(
- real_main, &cargo::Config::default().unwrap(),
- usage, &args, false);
- assert_eq!(result.unwrap(), Some("foo <version>".to_string()));
-}
+++ /dev/null
-use std::io::prelude::*;
-use std::io;
-use std::sync::{Arc, Mutex};
-use term::{Terminal, TerminfoTerminal, color};
-use hamcrest::{assert_that};
-
-use cargo::core::shell::{Shell, ShellConfig};
-use cargo::core::shell::ColorConfig::{Auto,Always, Never};
-use cargo::util::CargoResult;
-
-use support::{Tap, execs, shell_writes};
-
-struct Sink(Arc<Mutex<Vec<u8>>>);
-
-impl Write for Sink {
- fn write(&mut self, data: &[u8]) -> io::Result<usize> {
- Write::write(&mut *self.0.lock().unwrap(), data)
- }
- fn flush(&mut self) -> io::Result<()> { Ok(()) }
-}
-
-#[test]
-fn non_tty() {
- let config = ShellConfig { color_config: Auto, tty: false };
- let a = Arc::new(Mutex::new(Vec::new()));
-
- Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| {
- shell.say("Hey Alex", color::RED).unwrap();
- });
- let buf = a.lock().unwrap().clone();
- assert_that(&buf[..], shell_writes("Hey Alex\n"));
-}
-
-#[test]
-fn color_explicitly_disabled() {
- let term = TerminfoTerminal::new(Vec::new());
- if term.is_none() { return }
-
- let config = ShellConfig { color_config: Never, tty: true };
- let a = Arc::new(Mutex::new(Vec::new()));
-
- Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| {
- shell.say("Hey Alex", color::RED).unwrap();
- });
- let buf = a.lock().unwrap().clone();
- assert_that(&buf[..], shell_writes("Hey Alex\n"));
-}
-
-#[test]
-fn colored_shell() {
- let term = TerminfoTerminal::new(Vec::new());
- if term.is_none() { return }
-
- let config = ShellConfig { color_config: Auto, tty: true };
- let a = Arc::new(Mutex::new(Vec::new()));
-
- Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| {
- shell.say("Hey Alex", color::RED).unwrap();
- });
- let buf = a.lock().unwrap().clone();
- assert_that(&buf[..],
- shell_writes(colored_output("Hey Alex\n",
- color::RED).unwrap()));
-}
-
-#[test]
-fn color_explicitly_enabled() {
- let term = TerminfoTerminal::new(Vec::new());
- if term.is_none() { return }
-
- let config = ShellConfig { color_config: Always, tty: false };
- let a = Arc::new(Mutex::new(Vec::new()));
-
- Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| {
- shell.say("Hey Alex", color::RED).unwrap();
- });
- let buf = a.lock().unwrap().clone();
- assert_that(&buf[..],
- shell_writes(colored_output("Hey Alex\n",
- color::RED).unwrap()));
-}
-
-#[test]
-fn no_term() {
- // Verify that shell creation is successful when $TERM does not exist.
- assert_that(::cargo_process().env_remove("TERM"),
- execs().with_stderr(""));
-}
-
-fn colored_output(string: &str, color: color::Color) -> CargoResult<String> {
- let mut term = TerminfoTerminal::new(Vec::new()).unwrap();
- try!(term.reset());
- try!(term.fg(color));
- try!(write!(&mut term, "{}", string));
- try!(term.reset());
- try!(term.flush());
- Ok(String::from_utf8_lossy(term.get_ref()).to_string())
-}
+++ /dev/null
-#![deny(warnings)]
-
-extern crate bufstream;
-extern crate cargo;
-extern crate filetime;
-extern crate flate2;
-extern crate git2;
-extern crate hamcrest;
-extern crate libc;
-extern crate rustc_serialize;
-extern crate tar;
-extern crate tempdir;
-extern crate term;
-extern crate url;
-#[cfg(windows)] extern crate kernel32;
-#[cfg(windows)] extern crate winapi;
-
-#[macro_use]
-extern crate log;
-
-use cargo::util::Rustc;
-use std::ffi::OsStr;
-use std::time::Duration;
-
-mod support;
-
-mod test_bad_config;
-mod test_bad_manifest_path;
-mod test_cargo;
-mod test_cargo_bench;
-mod test_cargo_build_auth;
-mod test_cargo_build_lib;
-mod test_cargo_clean;
-mod test_cargo_compile;
-mod test_cargo_compile_custom_build;
-mod test_cargo_compile_git_deps;
-mod test_cargo_compile_path_deps;
-mod test_cargo_compile_plugins;
-mod test_cargo_compile_rustflags;
-mod test_cargo_cross_compile;
-mod test_cargo_doc;
-mod test_cargo_features;
-mod test_cargo_fetch;
-mod test_cargo_freshness;
-mod test_cargo_generate_lockfile;
-mod test_cargo_init;
-mod test_cargo_install;
-mod test_cargo_metadata;
-mod test_cargo_new;
-mod test_cargo_package;
-mod test_cargo_profiles;
-mod test_cargo_overrides;
-mod test_cargo_publish;
-mod test_cargo_read_manifest;
-mod test_cargo_registry;
-mod test_cargo_run;
-mod test_cargo_concurrent;
-mod test_cargo_rustc;
-mod test_cargo_rustdoc;
-mod test_cargo_search;
-mod test_cargo_test;
-mod test_cargo_tool_paths;
-mod test_cargo_config;
-mod test_cargo_verify_project;
-mod test_cargo_version;
-mod test_shell;
-mod test_cargo_death;
-mod test_cargo_cfg;
-mod test_cargo_net_config;
-
-thread_local!(static RUSTC: Rustc = Rustc::new("rustc").unwrap());
-
-fn rustc_host() -> String {
- RUSTC.with(|r| r.host.clone())
-}
-
-fn is_nightly() -> bool {
- RUSTC.with(|r| {
- r.verbose_version.contains("-nightly") ||
- r.verbose_version.contains("-dev")
- })
-}
-
-fn process<T: AsRef<OsStr>>(t: T) -> cargo::util::ProcessBuilder {
- let mut p = cargo::util::process(t.as_ref());
- p.cwd(&support::paths::root())
- .env_remove("CARGO_HOME")
- .env("HOME", support::paths::home())
- .env("CARGO_HOME", support::paths::home().join(".cargo"))
- .env_remove("RUSTC")
- .env_remove("RUSTFLAGS")
- .env_remove("XDG_CONFIG_HOME") // see #2345
- .env("GIT_CONFIG_NOSYSTEM", "1") // keep trying to sandbox ourselves
- .env_remove("CARGO_TARGET_DIR") // we assume 'target'
- .env_remove("MSYSTEM"); // assume cmd.exe everywhere on windows
- return p
-}
-
-fn cargo_process() -> cargo::util::ProcessBuilder {
- process(&support::cargo_dir().join("cargo"))
-}
-
-fn sleep_ms(ms: u64) {
- std::thread::sleep(Duration::from_millis(ms));
-}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use cargotest::rustc_host;
+use cargotest::support::{path2url, project, execs};
+use hamcrest::assert_that;
+
+#[test]
+fn pathless_tools() {
+ let target = rustc_host();
+
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo"
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", &format!(r#"
+ [target.{}]
+ ar = "nonexistent-ar"
+ linker = "nonexistent-linker"
+ "#, target));
+
+ assert_that(foo.cargo_process("build").arg("--verbose"),
+ execs().with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({url})
+[RUNNING] `rustc [..] -C ar=nonexistent-ar -C linker=nonexistent-linker [..]`
+", url = foo.url())))
+}
+
+#[test]
+fn absolute_tools() {
+ let target = rustc_host();
+
+ // Escaped as they appear within a TOML config file
+ let config = if cfg!(windows) {
+ (r#"C:\\bogus\\nonexistent-ar"#, r#"C:\\bogus\\nonexistent-linker"#)
+ } else {
+ (r#"/bogus/nonexistent-ar"#, r#"/bogus/nonexistent-linker"#)
+ };
+
+ let foo = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo"
+ "#)
+ .file("src/lib.rs", "")
+ .file(".cargo/config", &format!(r#"
+ [target.{target}]
+ ar = "{ar}"
+ linker = "{linker}"
+ "#, target = target, ar = config.0, linker = config.1));
+
+ let output = if cfg!(windows) {
+ (r#"C:\bogus\nonexistent-ar"#, r#"C:\bogus\nonexistent-linker"#)
+ } else {
+ (r#"/bogus/nonexistent-ar"#, r#"/bogus/nonexistent-linker"#)
+ };
+
+ assert_that(foo.cargo_process("build").arg("--verbose"),
+ execs().with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({url})
+[RUNNING] `rustc [..] -C ar={ar} -C linker={linker} [..]`
+", url = foo.url(), ar = output.0, linker = output.1)))
+}
+
+#[test]
+fn relative_tools() {
+ let target = rustc_host();
+
+ // Escaped as they appear within a TOML config file
+ let config = if cfg!(windows) {
+ (r#".\\nonexistent-ar"#, r#".\\tools\\nonexistent-linker"#)
+ } else {
+ (r#"./nonexistent-ar"#, r#"./tools/nonexistent-linker"#)
+ };
+
+ // Funky directory structure to test that relative tool paths are made absolute
+ // by reference to the `.cargo/..` directory and not to (for example) the CWD.
+ let origin = project("origin")
+ .file("foo/Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo"
+ "#)
+ .file("foo/src/lib.rs", "")
+ .file(".cargo/config", &format!(r#"
+ [target.{target}]
+ ar = "{ar}"
+ linker = "{linker}"
+ "#, target = target, ar = config.0, linker = config.1));
+
+ let foo_path = origin.root().join("foo");
+ let foo_url = path2url(foo_path.clone());
+ let prefix = origin.root().into_os_string().into_string().unwrap();
+ let output = if cfg!(windows) {
+ (format!(r#"{}\.\nonexistent-ar"#, prefix),
+ format!(r#"{}\.\tools\nonexistent-linker"#, prefix))
+ } else {
+ (format!(r#"{}/./nonexistent-ar"#, prefix),
+ format!(r#"{}/./tools/nonexistent-linker"#, prefix))
+ };
+
+ assert_that(origin.cargo_process("build").cwd(foo_path).arg("--verbose"),
+ execs().with_stderr(&format!("\
+[COMPILING] foo v0.0.1 ({url})
+[RUNNING] `rustc [..] -C ar={ar} -C linker={linker} [..]`
+", url = foo_url, ar = output.0, linker = output.1)))
+}
--- /dev/null
+extern crate cargotest;
+extern crate hamcrest;
+
+use cargotest::support::{project, execs, main_file, basic_bin_manifest};
+use hamcrest::{assert_that};
+
+fn verify_project_success_output() -> String {
+ r#"{"success":"true"}"#.into()
+}
+
+#[test]
+fn cargo_verify_project_path_to_cargo_toml_relative() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("verify-project")
+ .arg("--manifest-path").arg("foo/Cargo.toml")
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(0)
+ .with_stdout(verify_project_success_output()));
+}
+
+#[test]
+fn cargo_verify_project_path_to_cargo_toml_absolute() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("verify-project")
+ .arg("--manifest-path").arg(p.root().join("Cargo.toml"))
+ .cwd(p.root().parent().unwrap()),
+ execs().with_status(0)
+ .with_stdout(verify_project_success_output()));
+}
+
+#[test]
+fn cargo_verify_project_cwd() {
+ let p = project("foo")
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+ assert_that(p.cargo_process("verify-project")
+ .cwd(p.root()),
+ execs().with_status(0)
+ .with_stdout(verify_project_success_output()));
+}
--- /dev/null
+extern crate cargo;
+extern crate cargotest;
+extern crate hamcrest;
+extern crate rustc_serialize;
+
+use cargotest::support::{project, execs};
+use hamcrest::assert_that;
+
+#[test]
+fn simple() {
+ let p = project("foo");
+
+ assert_that(p.cargo_process("version"),
+ execs().with_status(0).with_stdout(&format!("{}\n",
+ cargo::version())));
+
+ assert_that(p.cargo_process("--version"),
+ execs().with_status(0).with_stdout(&format!("{}\n",
+ cargo::version())));
+
+}
+
+#[derive(RustcDecodable)]
+struct FooFlags {
+ flag_version: bool,
+}
+
+fn real_main(flags: FooFlags, _config: &cargo::Config) ->
+ cargo::CliResult<Option<String>> {
+ if flags.flag_version {
+ Ok(Some("foo <version>".to_string()))
+ } else {
+ Ok(None)
+ }
+}
+
+#[test]
+fn subcommand_with_version_using_exec_main_without_stdin() {
+ let usage = "
+Usage: cargo foo [--version]
+
+Options:
+ -V, --version Print version info
+";
+ let args: Vec<String> = vec!["cargo", "foo", "--version"]
+ .into_iter().map(|s| s.to_string()).collect();
+ let result = cargo::call_main_without_stdin(
+ real_main, &cargo::Config::default().unwrap(),
+ usage, &args, false);
+ assert_eq!(result.unwrap(), Some("foo <version>".to_string()));
+}